leetcode【陣列】兩數之和 -python3
給定一個整數陣列和一個目標值,找出陣列中和為目標值的兩個數。
你可以假設每個輸入只對應一種答案,且同樣的元素不能被重複利用。
示例:
給定 nums = [2, 7, 11, 15], target = 9
因為 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
試解:
class Solution: def twoSum(self, nums, target): """ :type nums: List[int] :type target: int :rtype: List[int] """ ans = [] for i in range(len(nums)-1): j = i + 1 while (j) <= (len(nums)-1): if nums[i] + nums[j] == target: ans.append(i) ans.append(j) return ans else: j += 1
簡單的資料測試可以通過:
但是對於複雜陣列時間會超時:
進行了兩次迴圈時間複雜度為O(N^2)
改進:快速排序演算法,從最大最小加和開始和target比較,如果和過大,則縮小最大值;如果和過小,則放大最小值:
class Solution: def twoSum(self, nums, target): """ :type nums: List[int] :type target: int :rtype: List[int] """ ans = [] new=nums[:] new.sort() i=0 #lable min of nums j=len(new)-1 #lable max of nums while i<len(new) and j>0: if new[i]+new[j] == target: a=nums.index(new[i]) b=nums.index(new[j],a) #此處避免a=b ans.append(a) ans.append(b) return ans elif new[i]+new[j] > target: j-=1 elif new[i]+new[j] < target: i+=1
測試仍未通過,因為只考慮了target是正值的情況:
這裡出錯是因為先找到了a=4(nums[4]=-5),按照b=nums.index(new[j],a),只能往後面去找-3,是找不到的,所以會出錯,這句就應該改掉了改正:
class Solution: def twoSum(self, nums, target): """ :type nums: List[int] :type target: int :rtype: List[int] """ ans = [] new=nums[:] new.sort() i=0 #lable min of nums j=len(new)-1 #lable max of nums while i<len(new) and j>0: if new[i]+new[j] == target: a=nums.index(new[i]) nums[a]='replace' #replace in nums b=nums.index(new[j]) ans.append(a) ans.append(b) return ans elif new[i]+new[j] > target: j-=1 elif new[i]+new[j] < target: i+=1
測試通過。
這樣時間複雜度變成快速排序演算法的O(nlogn),用了52ms
網上看到可以用enumerate() 函式遍歷,enumerate() 函式釋義,摘錄如下:
描述
enumerate() 函式用於將一個可遍歷的資料物件(如列表、元組或字串)組合為一個索引序列,同時列出資料和資料下標,一般用在 for 迴圈當中。
Python 2.3. 以上版本可用,2.6 新增 start 引數。
語法
以下是 enumerate() 方法的語法:
enumerate(sequence, [start=0])
引數
- sequence -- 一個序列、迭代器或其他支援迭代物件。
- start -- 下標起始位置。
返回值
返回 enumerate(列舉) 物件。
例項
以下展示了使用 enumerate() 方法的例項:
>>>seasons = ['Spring', 'Summer', 'Fall', 'Winter']
>>> list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
>>> list(enumerate(seasons, start=1)) # 小標從 1 開始
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
普通的 for 迴圈
>>>i = 0
>>> seq = ['one', 'two', 'three']
>>> for element in seq:
... print i, seq[i]
... i +=1
...
0 one
1 two
2 three
for 迴圈使用 enumerate
>>>seq = ['one', 'two', 'three']
>>> for i, element in enumerate(seq):
... print i, element
...
0 one
1 two
2 three
演算法改進如下:
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
result = []
for i, value in enumerate(nums):
if (target - value) in nums[i+1:]:
result.append(nums.index(value))
nums[i]='replace'
result.append(nums.index(target-value))
return result
但是其實變得更慢了哈哈哈哈哈哈,why!1260ms