1. 程式人生 > 實用技巧 >[LeetCode] 1. Two Sum(兩數之和)

[LeetCode] 1. Two Sum(兩數之和)

Description

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

給定一個整數陣列 nums 和一個整數 target陣列內相加和等於 target 的兩個元素的下標

You may assume that each input would have exactly one solution

, and you may not use the same element twice.

你可以假定每組輸入有且僅有一個輸出,並且你不能使用同一個元素兩次。

You can return the answer in any order.

你可以以任意順序返回答案。

Examples

Example 1

Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Output: Because nums[0] + nums[1] == 9, we return [0, 1].

Example 2

Input: nums = [3,2,4], target = 6
Output: [1,2]

Example 3

Input: nums = [3,3], target = 6
Output: [0,1]

Constraints

  • 2 <= nums.length <= 10^5

  • -10^9 <= nums[i] <= 10^9

  • -10^9 <= target <= 10^9

  • Only one valid answer exists

Hints

  1. A really brute force way would be to search for all possible pairs of numbers but that would be too slow. Again, it's best to try out brute force solutions for just for completeness. It is from thses brute force solutions that you can come up with optimizations.

    一個真的很暴力的方案是遍歷陣列內可能的元素對,那樣真的太慢了。但,最好還是用暴力法先把這題過了。在暴力求解的過程中,自然就能想到優化方案。

  2. so, if we fix one of the numbers, say x, we have to scan the entire array to find the next number y which is value - x, where value is the input parameter. Can we change our array somehow so that this search becomes faster?

    所以,如果我們固定一個數(記為 x),我們需要掃描整個陣列去尋找一個 y,其中 ytarget - x。我們能否修改陣列使得這一搜索變得更高效?

  3. The second train of thought is, without changing the array, can we use additional space somehow? Like maybe a hash map to speed up the search?

    第二種想法是,不改變原有陣列,我們能否使用一點額外空間?比如使用雜湊表加速查詢?

Solution

首先,暴力遍歷的方法確實可行,不過正如題目所說,可以用點額外空間儲存一些資訊,使得搜尋不那麼暴力。這裡建立了一個 map,對映關係是陣列元素到陣列元素下標。注意這個 map 並不是一開始就建立好的,而是在遍歷陣列的過程中建立起來的。如果一開始就建立好的話,首先解決不了重複元素的問題(參見樣例資料 3),而且也難以做到一個元素只用一次(參見樣例資料 2)。最終程式碼只需遍歷一次陣列便能找到結果。程式碼如下:

class Solution {
    fun twoSum(nums: IntArray, target: Int): IntArray {
        // 建立從陣列元素到元素下標的對映
        val map = hashMapOf<Int, Int>()

        for (i in nums.indices) {
            // 對於陣列中的每個元素
            // 我們找另一個對應的元素(target - nums[i])是否出現過
            // 出現過即為所求
            if (map.containsKey(target - nums[i])) {
                return intArrayOf(map.getValue(target - nums[i]), i)
            }
            // 沒出現過,將當前元素和對應下標存入 map(可能與之匹配的元素在這之後)
            map[nums[i]] = i
        }

        // 題目說解一定存在,所以這一句實際上並不會執行
        return intArrayOf(-1, -1)
    }
}