[python]LeetCode_167. Two Sum II - Input Array Is Sorted
文章目录
牽涉概念及時間紀錄
20220408 17:08-17:20 for 第一次
使用雙指針方式能降低時間複雜度
當需要雙迴圈時可以往此方向考慮
一、題目內容
簡而言之:
就是給定一個list 裡面有很多數字,以及一個目標數字。
請找出其中哪兩數字相加之後會與目標數字吻合。
必有唯一解,且同一位置不重複使用(ex 不會有[2,2]這種答案)
以下題目原文:
Given a 1-indexed array of integers numbers that is already sorted in non-decreasing order,
find two numbers such that they add up to a specific target number.
Let these two numbers be numbers[index1] and numbers[index2]
where 1 <= index1 < index2 <= numbers.length.
Return the indices of the two numbers, index1 and index2,
added by one as an integer array [index1, index2] of length 2.
The tests are generated such that there is exactly one solution.
You may not use the same element twice.
Your solution must use only constant extra space.
Example 1:
Input: numbers = [2,7,11,15], target = 9
Output: [1,2]
Explanation: The sum of 2 and 7 is 9. Therefore, index1 = 1, index2 = 2. We return [1, 2].
Example 2:
Input: numbers = [2,3,4], target = 6
Output: [1,3]
Explanation: The sum of 2 and 4 is 6. Therefore index1 = 1, index2 = 3. We return [1, 3].
Example 3:
Input: numbers = [-1,0], target = -1
Output: [1,2]
Explanation: The sum of -1 and 0 is -1. Therefore index1 = 1, index2 = 2. We return [1, 2].
Constraints:
2 <= numbers.length <= 3 * 104
-1000 <= numbers[i] <= 1000
numbers is sorted in non-decreasing order.
-1000 <= target <= 1000
The tests are generated such that there is exactly one solution.
二、想法思路
1.直觀想法:
一開始不假思索就是遍歷查找一遍就應該有答案了?
fish yes (於是,抱歉我突然想耍白痴一下XD)
就直接使用迴圈從頭開始找,並注意一些可能造成無效計算的情況。
諸如相同的重複字元(ex 0,0,0,1,2,3 這樣的)
時間複雜度為O(N^2)
空間複雜度為O(1).
def twoSum(self, numbers: List[int], target: int) -> List[int]:
numbers_l = len(numbers)
for num in range(numbers_l):
if num > 0:
# ignore same number that has already calculate.
if numbers[num] == numbers[num-1]:
continue
for num_in in range(num+1, numbers_l):
if target == numbers[num] + numbers[num_in]:
return [num+1, num_in+1]
elif target < numbers[num] + numbers[num_in]:
break
2.想想發現不太對,優化一下:
這邊由於題目已經明確說明是non-decreasing order了,
用指標的想法去做,可以將時間降低不少.
一開始將指標指在最小與最大,逐步往中間靠攏即可找到符合的答案。
時間複雜度為O(N)
空間複雜度為O(1).
def twoSum(self, numbers: List[int], target: int) -> List[int]:
numbers_l = len(numbers)
# little is the less pointer, and the big is the large pointer
little = 0
big = numbers_l-1
while numbers[little] + numbers[big] != target:
if numbers[little] + numbers[big] > target:
big -= 1
while numbers[big] == numbers[big-1] and numbers[little] + numbers[big] > target:
big -= 1
else:
little += 1
while numbers[little] == numbers[little+1] and numbers[little] + numbers[big] < target:
little +=1
return [little+1, big+1]
总结
這題第一種應該大部分人都會直覺想到這樣做,畢竟暴力解始終是種解。
但不知道是否我哪裡沒有寫好,兩種作法在leetcode上的時間幾乎一樣。
如果有知道哪裡有問題的大神,麻煩告訴我一下。
感謝花時間看到這裡的大家。
如果有錯,請不吝告知,也可以一起討論,一起加油XD