iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 3
2
Software Development

透過 LeetCode 解救美少女工程師的演算法人生系列 第 3

[Day 3] 演算法刷題 LeetCode 1. Two Sum (Easy)

  • 分享至 

  • xImage
  •  

題目


https://leetcode.com/problems/two-sum/

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

解答


C#

public class Solution {
    public int[] TwoSum(int[] nums, int target) {
        Dictionary<int, int> temp = new Dictionary<int, int>();
        for (int i = 0; i < nums.Length; i++)
        {
            int left = target - nums[i];
            if (temp.ContainsKey(left))
            {
                return new int[] { temp[left], i  };
            }
            if (!temp.ContainsKey(nums[i]))
            {
                temp.Add(nums[i], i);
            }
        }
        return null;
    }
}

結果


Runtime: 264 ms, faster than 81.11% of C# online submissions for Two Sum.

Memory Usage: 29.2 MB, less than 51.69% of C# online submissions for Two Sum.

Time Complexity: O(n)

Space Complextiy: O(n)


為什麼我要這樣做?


本來一開始我是使用暴力法──用兩個for迴圈去解決,但是這樣發現是O(n^2)後,就試圖用更好的方式去寫。

  1. 用 for 迴圈計算 target 減去 nums 的 left(餘數)
  2. 檢查 Dictionary 裡有沒有已存在的餘數
    • 如果,則回傳 Dictionary 的餘數 array 裡的 index 及現在的 index
      • 因為 target = Dictionary[left] + nums[index]
    • 如果沒有,則記錄此次 餘數index 到 Dictionary 裡
  3. 如果都找不到就回傳 null

這樣我就可以用一個 for 迴圈邊算每個 nums 的餘數、邊找有沒有符合的答案。


以上就是這次 LeetCode 刷題的分享啦!
如果其它人有更棒的想法及意見,請留言或寄信(t4730@yahoo.com.tw) 給我。
那我們就下回見囉 /images/emoticon/emoticon07.gif


上一篇
[Day 2] 演算法複雜度分析──時間複雜度(Time Complexity)、空間複雜度(Space Complexity)
下一篇
[Day 4] 演算法刷題 LeetCode 20. Valid Parentheses (Easy)
系列文
透過 LeetCode 解救美少女工程師的演算法人生31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
rockywang
iT邦新手 5 級 ‧ 2019-10-13 14:19:33

先存到 map 用 map 的 hashcode 的原因去找值,會比這快多。

初學者剛練習了一題而已,互相學習 :)

		Map<Integer, Integer> map = new HashMap<Integer, Integer>();
		for (int i=0; i<nums.length; i++)
			map.put(nums[i], i);
		
		for (int i=0; i<nums.length; i++) {
			
			int diff = target - nums[i];
			if (map.containsKey(diff) && map.get(diff) != i)
				return new int[] {i, map.get(diff)};
		}

		throw new RuntimeException("no matched nums");
Fion iT邦新手 5 級 ‧ 2019-10-16 21:01:05 檢舉

我也不是非常非常理解所有的物件形態,感謝你的分享~保持交流~~
/images/emoticon/emoticon07.gif

rockywang iT邦新手 5 級 ‧ 2019-10-18 23:17:36 檢舉

https://www.books.com.tw/products/0010771263 好像是這本吧,有講到 array 是依序找的,但 hashmap 是直接 hash 出值再 mode 找到位置,快速非常多,可以參考看看,該書圖解的蠻清楚的

0
w4560000
iT邦研究生 5 級 ‧ 2020-05-10 23:07:30

我發現可以少寫一行判斷,Dictionary可以直接宣告Key的值
若有重複的Key,不會報錯,會直接覆蓋上去,只是會更改到結果
變成重複的值會取最後一個重複的Index
但還是會過關,這題剛好沒有Target取到重複值Index的TestCase
不過他題目也沒有說明重複值要取第一個還是最後一個,就無所謂了

        public int[] TwoSum(int[] nums, int target)
        {
            Dictionary<int, int> temp = new Dictionary<int, int>();

            for (int i = 0; i < nums.Length; i++)
            {
                int number = target - nums[i];

                if (temp.ContainsKey(number))
                    return new int[] { temp[number], i };

                temp[nums[i]] = i;
            }

            throw new ArgumentNullException();
        }

我要留言

立即登入留言