1. 程式人生 > >LeetCode演算法題-Two Sum II - Input array is sorted

LeetCode演算法題-Two Sum II - Input array is sorted

這是悅樂書的第179次更新,第181篇原創

01 看題和準備

今天介紹的是LeetCode演算法題中Easy級別的第38題(順位題號是167)。給定已按升序排序的整數陣列,找到兩個數字,使它們相加到特定的目標數。函式twoSum應該返回兩個數字的索引,使它們加起來到目標,其中index1必須小於index2。

注意

  • 返回的答案(index1和index2)不是從零開始的。

  • 可以假設每個輸入只有一個解決方案,並且您可能不會兩次使用相同的元素。

例如:

輸入:數字= [2,7,11,15],目標= 9

輸出:[1,2]

說明:2和7之和為9.因此index1 = 1,index2 = 2。


本次解題使用的開發工具是eclipse,jdk使用的版本是1.8,環境是win7 64位系統,使用Java語言編寫和測試。

02 第一種解法

此題和LeetCode演算法題的第一題Two Sum類似,不過此題定義和條件更加清晰,規定了只存在唯一解,並且將陣列進行了排序。

和以前一樣,第一種解法是暴力解法,使用雙層迴圈,依次遍歷相加判斷和是否等於目標值,直到找到兩元素為止。但是元素的索引需要加1,因為題目要求索引不從0開始。

特殊情況:當陣列為空或者其長度小於2時,直接返回空。

public int[] twoSum (int[] numbers, int target) {
    if (numbers == null || numbers.length < 2) {
        return null;
    }
    int[] index = new int[2];
    for(int i = 0; i < numbers.length; i++) {
        for(int j = i+1; j < numbers.length; j++) {
            if (numbers[i] + numbers[j] == target) {
                index[0] = i+1;
                index[1] = j+1;
            }
        }
    }
    return index[0] == 0 ? null : index;
}

此解法時間複雜度是O(n^2),空間複雜度是O(1)。

03 第二種解法

使用HashMap,遍歷陣列時,判斷當前元素和目標值之間的差值是否存在map中,如果存在,就返回map中此元素的value,即其索引,和當前元素的索引;否則,將當前元素作為key,索引作為value存入map中,然後進行下一次迴圈。

特殊情況:當陣列為空或者其長度小於2時,直接返回空。

public int[] twoSum2 (int[] numbers, int target) {
    if (numbers == null || numbers.length < 2) { 
        return null;
    }
    int[] index = new int[2];
    Map<Integer,Integer> map = new HashMap<Integer,Integer>();
    for (int k=0; k<numbers.length; k++) {
        if (map.containsKey(target-numbers[k])) {
            index[0] = map.get(target-numbers[k]);
            index[1] = k+1;
        }
        map.put(numbers[k], k+1);
    }
    return index[0] == 0 ? null : index;
}

時間複雜度是O(n),空間複雜度是O(n)。

04 第三種解法

既然陣列已經是排過序的,使用雙指標,每次從前往後和從後往前各取一個元素,判斷兩數之和是否等於目標值,如果小於目標值,則從前往後的指標向前移動一位;如果大於目標值,則從後往前的指標向前移動一位,直到兩數之和等於目標值即可。

特殊情況:當陣列為空或者其長度小於2時,直接返回空。

public int[] twoSum3(int[] numbers, int target) {
    if (numbers == null || numbers.length < 2) { 
        return null;
    }
    int start = 0;
    int end = numbers.length - 1;
    while (start < end) {
        int sum = numbers[start] + numbers[end];
        if (sum == target) {
            return new int[] {start+1, end+1};
        } else if (sum < target) {
            start++;
        } else {
            end--;
        }
    }
    return null;
}

此解法的時間複雜度是O(n),空間複雜度是O(1)。

05 小結

演算法專題目前已連續日更超過一個月,演算法題文章38+篇,公眾號對話方塊回覆【資料結構與演算法】、【演算法】、【資料結構】中的任一關鍵詞,獲取系列文章合集。

以上就是全部內容,如果大家有什麼好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、轉發就是對我最大的回報和支援!