問題描述
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
給定一個整數數組,返回兩個數字的索引,使它們加起來等於一個特定的目標。
可以假設每個輸入將只有一個解決方案,並且不能兩次使用相同的元素。
給定 nums = [2, 7, 11, 15], target = 9,
因爲nums[0] + nums[1] = 2 + 7 = 9,
因此返回 [0, 1].
python 實現
實現一:
直接利用 python 列表和切片的性質,在列表剩下的部分裏查找是否存在能與當前相加得到目標值的數。雖然看上去代碼量很少,但是這種方法存在的問題是,每次查找都需要進行切片操作,而 python 的切片操作每次都會使用新的內容來存儲切片得到的結果,因此這種方法會比較耗內存。
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
for i, n in enumerate(nums):
if target-n in nums[i+1: ]:
return [i, nums[i+1: ].index(target-n)+i+1]
實現二:
使用散列表(比如字典)來記錄已經出現過的值,以值作爲 key,索引作爲 val。這樣做的好處是,一方面可以直接根據值來獲取對應在列表裏的索引,另一方面,散列表的讀取速度比較快,時間和空間上消耗比較小。
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
dic = {} # key: value, val: index
for i, n in enumerate(nums):
if target-n in dic.keys():
return [dic[target-n], i]
else:
dic[n] = i
特殊情況
如果入參 nums 是一個滿足升序的有序表,由於肯定存在有且只有一組數相加之和等於目標值,因此其他組合的結果要麼大於目標值,要麼小於目標值。那我們就可以分別在首尾用一個變量記錄索引,兩個索引逐步往中間靠攏,必然能找出符合要求的兩個索引值。
這種實現方法能避免創建額外的內存空間,而且時間複雜度也相對較小,但是前提條件有點太理想。如果入參不是有序的,再手動排序使用這個方法,找到兩個值之後還要回到原數組去找到相應的索引,這樣的操作也太複雜了。不過這也是一種思路的拓展啦,畢竟從首尾分別使用一個指針進行定位這種技巧在很多算法題都是有用的。
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
head = 0
tail = len(nums) - 1
while head < tail:
if nums[head] + nums[tail] == target:
return [head, tail]
elif nums[head] + nums[tail] > target:
tail -= 1
else:
# nums[head] + nums[tail] < target
head += 1
return [None, None]
鏈接:https://leetcode.com/problems/two-sum/