Leetcode 167:兩數之和 II - 輸入有序陣列(最詳細解決方案!!!)
給定一個已按照升序排列 的有序陣列,找到兩個數使得它們相加之和等於目標數。
函式應該返回這兩個下標值 index1 和 index2,其中 index1 必須小於 index2。
說明:
- 返回的下標值(index1 和 index2)不是從零開始的。
- 你可以假設每個輸入只對應唯一的答案,而且你不可以重複使用相同的元素。
示例:
輸入: numbers = [2, 7, 11, 15], target = 9
輸出: [1,2]
解釋: 2 與 7 之和等於目標數 9 。因此 index1 = 1, index2 = 2 。
解題思路
首先想到的解決思路是通過兩次迴圈,每次迴圈遍歷列表,這種演算法的時間複雜度是O(n^2)
。(這是我們在Leetcode 1 兩數之和中提到的解決方案)
class Solution:
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
nums_len = len(numbers)
for i in range(nums_len):
for j in range(i + 1, nums_len):
if numbers[i] + numbers[j] == target:
return [i + 1, j + 1]
return []
但是很明顯,這種暴力解法在這問題中顯得很蠢(⊙﹏⊙)
我們知道這個資料是有序的,那麼我們很容易聯想到使用二分搜尋法是不是可以用於這個問題呢?我們可以每次判斷target-num[i]
對應的值是否在num[i+1:]
中,這個時候演算法的複雜度變成了O(nlogn)
。
class Solution:
def _BinarySearch(self, numbers, target):
l = 0
r = len(numbers) - 1
while l <= r:
mid = (l + r) // 2
if target == numbers[mid]:
return mid
elif target < numbers[mid]:
r = mid - 1
else:
l = mid + 1
return -1
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
nums_len = len(numbers)
for i in range(nums_len):
dif = target - numbers[i]
dif_index = self._BinarySearch(numbers[i + 1:], dif)
if dif_index != -1:
return [i + 1, dif_index + i + 2]
return []
那麼我們就想有沒有O(n)
級別的做法呢?我們依然可以參考之前Leetcode 1 兩數之和中使用hash
表的方法,但是這種做法的空間複雜度就變成了O(n)
。我們有沒有空間複雜度O(1)
,時間複雜度O(n)
的做法呢?我們要充分利用題目給的條件:有序陣列
0 1 2 3 4 5 6 7
l-> <-r
我們可以這樣想,我們首先判斷首尾兩項的和是不是target
,如果比target
小,那麼我們左邊+1
位置的數(比左邊
位置的數大)再和右相相加,繼續判斷。如果比target
大,那麼我們右邊-1
位置的數(比右邊位置的數小
)再和左相相加,繼續判斷。我們通過這樣不斷放縮的過程,就可以在O(n)
的時間複雜度內找到對應的座標位置。(這和快速排序的思路很相似)
class Solution:
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
l = 0
r = len(numbers) - 1
while l < r:
if numbers[l] + numbers[r] == target:
return [l + 1, r + 1]
elif numbers[l] + numbers[r] < target:
l += 1
else:
r -= 1
return []
這種解法叫做對撞指標法
,又叫做雙索引法
。
該問題的其他語言版本新增到了我的GitHub Leetcode
如有問題,希望大家指出!!!
相關文章
- 兩數之和詳細解答
- 兩數之和,返回陣列下標陣列
- 兩個有序陣列的中位數陣列
- [陣列]Leetcode15三數之和陣列LeetCode
- Leetcode[陣列] 18. 四數之和LeetCode陣列
- python輸入詳解(陣列、矩陣)Python陣列矩陣
- 【LeetCode】88. 合併兩個有序陣列LeetCode陣列
- LeetCode--尋找兩個有序陣列的中位數(05)LeetCode陣列
- 輸出陣列nums中兩數之和為target的對應下標陣列
- Leetcode 344:驗證迴文串(最詳細解決方案!!!)LeetCode
- LeetCode:兩數之和LeetCode
- LeetCode - 兩數之和LeetCode
- 兩個有序陣列如何合併成一個有序陣列陣列
- 將兩個有序陣列合併為一個有序陣列陣列
- LeetCode解題(C++)-4. 尋找兩個有序陣列的中位數LeetCodeC++陣列
- LeetCode第4題:尋找兩個有序陣列的中位數LeetCode陣列
- [LeetCode] Median of Two Sorted Arrays 兩個有序陣列的中位數LeetCode陣列
- 尋找兩個有序陣列的中位數陣列
- 合併兩個有序陣列陣列
- LeetCode 1 兩數之和LeetCode
- leetcode #1 兩數之和LeetCode
- LeetCode之兩數之和LeetCode
- LeetCode-兩數之和LeetCode
- LeetCode-350-兩個陣列的交集 IILeetCode陣列
- LeetCode合併兩個有序陣列(逆向雙指標)LeetCode陣列指標
- leetCode解題記錄1 - 兩數之和LeetCode
- 88、合併兩個有序陣列陣列
- [LeetCode 刷題] 4. 尋找兩個有序陣列的中位數 (Hard)LeetCode陣列
- LeetCode: Two sum(兩數之和)LeetCode
- LeetCode 1. 兩數之和LeetCode
- LeetCode-1. 兩數之和LeetCode
- [LeetCode] Two Sum 兩數之和LeetCode
- 刪除有序陣列中的重複項 II陣列
- 每日一道 LeetCode (19):合併兩個有序陣列LeetCode陣列
- LeetCode每日一題:合併兩個有序陣列(No.88)LeetCode每日一題陣列
- 88. 合併兩個有序陣列陣列
- 【leetcode 簡單】第二十題 合併兩個有序陣列LeetCode陣列
- leetcode-0001 兩數之和LeetCode