天天看點

兩數之和 II - 輸入有序數組

給定一個已按照升序排列 的有序數組,找到兩個數使得它們相加之和等于目标數。

函數應該傳回這兩個下标值 index1 和 index2,其中 index1 必須小于 index2。

說明:

傳回的下标值(index1 和 index2)不是從零開始的。

你可以假設每個輸入隻對應唯一的答案,而且你不可以重複使用相同的元素。

示例:

輸入: numbers = [2, 7, 11, 15], target = 9

輸出: [1,2]

解釋: 2 與 7 之和等于目标數 9 。是以 index1 = 1, index2 = 2 。

解題思路:

  1. 首先 從 下标0開始,然後從1開始周遊,如果值是目标值,則輸出對應的下标。

    假設輸入inputs的數組為長度為n。

    時間複雜度 n + (n-1) + (n-1) + (n-2)+…+2+2+1 = n2 - 1 = o(n2)

    空間複雜度 o(n2)

  2. 首先 從 下标0開始,然後用目标值減去下标值1的 得到需要的值,然後在後面連接配接裡面查 出 結果傳回索引值。

    假設輸入inputs的數組為長度為n。

    時間複雜度 (n -1 ) log n + (n-2)log (n - 1) + (n-3)log(n - 2) + … + log(2) = o(nlog n)

    空間複雜度o(1)

  3. 使用雙指針,一個指針指向值較小的元素,一個指針指向值較大的元素。指向較小元素的指針從頭向尾周遊,指向較大元素的指針從尾向頭周遊。

    假設輸入inputs的數組為長度為n。

    時間複雜度 n = o(n)

    空間複雜度o(1)

public class TwoNumberSumSortInput {

    @Test
    public void twoSumTest() {
        int[] ints = twoSum(new int[]{2, 7, 11, 15}, 9);
        Assert.assertEquals(2, ints.length);
        Assert.assertEquals(1, ints[0]);
        Assert.assertEquals(2, ints[1]);
    }

    public int[] twoSum(int[] numbers, int target) {
        int i = 0, j = numbers.length - 1;
        while (i < j) {
            int sum = numbers[i] + numbers[j];
            if (sum == target) {
                return new int[]{i + 1, j + 1};
            } else if (sum < target) {
                i++;
            } else {
                j--;
            }
        }
        return null;
    }

}