Leetcode-Two Sum(java)

1 Description(描述)

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].
舉例:
給定一個數組nums=[2, 7, 11, 15],特定值爲target = 9,因爲nums[0] + nums[1] = 2 + 7 = 9,因此返回的是[0, 1]。

2 Solution(解決方案)

Approach 1: Brute Force(方法一:蠻力)
The brute force approach is simple. Loop through each element x and find if there is another value that equals to target - x.
蠻力方法很簡單。通過循環遍歷每個元素 x 並且尋找是否存在另一個等於特定值target - x 的值。

public int[] twoSum(int[] nums, int target) {
    for (int i = 0; i < nums.length; i++) {
        for (int j = i + 1; j < nums.length; j++) {
            if (nums[j] == target - nums[i]) {
                return new int[] { i, j };
            }
        }
    }
    throw new IllegalArgumentException("No two sum solution");
}

Complexity Analysis:(複雜度分析)

1 Time complexity : O(n2) For each element, we try to find its complement by looping through the rest of array which takes O(n) time. Therefore, the time complexity is O(n2).
1 時間複雜度:O(n2)。對於每個元素,我們都試圖通過遍歷數組中的其餘元素來找他的另一半加數,這花費了O(n)的時間。因此,時間複雜度爲O(n2)。

2 Space complexity : O(1).
2 空間複雜度: O(1)。

Approach 2: Two-pass Hash Table(使用兩次哈希表)
To improve our run time complexity, we need a more efficient way to check if the complement exists in the array. If the complement exists, we need to look up its index. What is the best way to maintain a mapping of each element in the array to its index? A hash table.
爲了優化我們的時間複雜度,我們需要一個更有效的方法來檢查是否在數組中有這樣的加數存在。如果存在,我們需要尋找他的索引。保持數組中每個元素與其索引關係映射的最好的方法是什麼?利用一個哈希表。

We reduce the look up time from O(n) to O(1) by trading space for speed. A hash table is built exactly for this purpose, it supports fast look up in near constant time. I say “near” because if a collision occurred, a look up could degenerate to O(n) time. But look up in hash table should be amortized O(1) time as long as the hash function was chosen carefully.
我們通過犧牲空間來換取速度的方式,將查找時間從O(n) 減少到了 O(1)。哈希表就是爲了這個目標才被建立的,他支持接近常量時間內的快速查找。我說的“接近”是因爲如果發生了檢測碰撞,查找時間將會退化成 O(n) 。但是隻要我們謹慎地選擇哈希方法,在哈希表中查找的時間應該平均爲O(1)。

A simple implementation uses two iterations. In the first iteration, we add each element’s value and its index to the table. Then, in the second iteration we check if each element’s complement (target - nums[i]) exists in the table. Beware that the complement must not be nums[i] itself!
一個簡單的實現通過兩次迭代。第一次迭代,我們將每個元素的值以及索引放入哈希表中。第二次迭代,我們檢查每個元素對應的加數(target - nums[i])是否存在於哈希表中。要注意的是,這個加數一定不能是nums[i]本身!

public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < nums.length; i++) {
        map.put(nums[i], i);
    }
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (map.containsKey(complement) && map.get(complement) != i) {
            return new int[] { i, map.get(complement) };
        }
    }
    throw new IllegalArgumentException("No two sum solution");
}

Complexity Analysis:(複雜度分析)
1 Time complexity : O(n). We traverse the list containing n elements exactly twice. Since the hash table reduces the look up time to O(1), the time complexity is O(n).
1 時間複雜度:O(n)。我們兩次遍歷包含 n 個元素的列表。但由於哈希表將查找的時間減少到了O(1),所以時間複雜度爲O(n)。

2 Space complexity : O(n). The extra space required depends on the number of items stored in the hash table, which stores exactly n elements.
2 空間複雜度:O(n)。所需的額外空間取決於哈希表中存儲的項的個數,哈希表恰好存儲了n個元素。

Approach 3: One-pass Hash Table(僅適用一次哈希表)
It turns out we can do it in one-pass. While we iterate and inserting elements into the table, we also look back to check if current element’s complement already exists in the table. If it exists, we have found a solution and return immediately.
當我們迭代元素並將其插入到表中時,我們還會回頭檢查當前元素的加數是否已經存在於表中。如果它存在,我們已經找到解決方法並立即返回。

public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (map.containsKey(complement)) {
            return new int[] { map.get(complement), i };
        }
        map.put(nums[i], i);
    }
    throw new IllegalArgumentException("No two sum solution");
}

Complexity Analysis:(複雜度分析)
1 Time complexity : O(n). We traverse the list containing n elements only once. Each look up in the table costs only O(1) time.
1 時間複雜度:O(n)。我們僅遍歷一次包含 n 個元素的列表。每次在哈希表中的查找僅花費O(1)的時間。

2 Space complexity : O(n). The extra space required depends on the number of items stored in the hash table, which stores at most n elements.
2 空間複雜度:O(n)。所需的額外空間取決於哈希表中存儲的項的個數,哈希表恰好存儲了n個元素。

注:內容均來源於leetcode。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章