1. 程式人生 > 其它 >力扣刷題筆記 167. 兩數之和 II - 輸入有序陣列

力扣刷題筆記 167. 兩數之和 II - 輸入有序陣列

問題描述

給你一個下標從1開始的整數陣列numbers,該陣列已按非遞減順序排列,請你從陣列中找出滿足相加之和等於目標數 target 的兩個數。如果設這兩個數分別是 numbers[index1] 和 numbers[index2] ,則 1 <= index1 < index2 <= numbers.length 。
以長度為 2 的整數陣列 [index1, index2] 的形式返回這兩個整數的下標 index1 和 index2。

示例1:

輸入:numbers = [2,7,11,15], target = 9
輸出:[1,2]
解釋:2 與 7 之和等於目標數 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。

示例2:

輸入:numbers = [2,3,4], target = 6
輸出:[1,3]
解釋:2 與 4 之和等於目標數 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。

解題思路:

雙指標

由於需要尋找陣列中兩個元素相加之和等於target的元素下標。且陣列是非遞減排列的,因此可以考慮使用雙指標的方式。

解法1

left指標以陣列的第一個位置作為初始條件,right指標始終以left指標+1位置作為初始條件。先用left指標確定第一個元素,然後使用right指標尋找陣列中是否有和left指標對應元素相加等於target值的,如果當right指標和left指標的和大於target時,則證明陣列中沒有與left指標對應元素相加等於target的數,因此,將left指標右移。依此迴圈,上述過程如圖所示:

def twoSum(numbers, target):
    left = 0
    length = len(numbers)
    while left <= length - 2:
        right = left + 1
        while right < length:
            if numbers[left] + numbers[right] == target:
                return [left + 1, right + 1]
            elif numbers[left] + numbers[right] > target:
                break
            else:
                pre_right = numbers[right]
                while numbers[right] == pre_right and right < length - 1:
                    right += 1
                if right == length - 1:
                    break
        if numbers[right] + numbers[left] == target:
            return [left + 1, right + 1]
        pre_left = numbers[left]
        while numbers[left] == pre_left:
            left += 1

解法2

left指標以陣列的第一個位置作為初始條件,right指標以陣列最後一個位置作為初始條件,left指標代表的是最小的元素值,right指標代表的是最大的元素值。若left指標對應的元素值和right指標對應的元素值相加小於target,則證明陣列中沒有與left指標對應元素相加等於target值得元素,left指標向右移。反之,若和大於target,則證明陣列中沒有與right值相加等於target值的元素,right右移。依此迴圈,上述過程如圖所示:

def twoSum2(numbers, target):
    left = 0
    right = len(numbers) - 1
    while left <= right:
        if numbers[left] + numbers[right] == target:
            return [left + 1, right + 1]
        elif numbers[left] + numbers[right] < target:
            left += 1
        else:
            right -= 1

可以看出,第二種方法比第一種方法的效率要高很多

直接遍歷

依次遍歷陣列中的每個元素,判斷target-元素i的值在陣列中是否存在,若存在,則放回

def twoSum(numbers, target):
    for i in range(len(numbers)):
        if target-numbers[i] in numbers:
            if numbers.index(target-numbers[i]) == i:
                return [i+1,i+2]
            return [i+1,numbers.index(target-numbers[i])+1]
            break