給定乙個整數陣列 nums 和乙個目標值 target,請你在該陣列中找出和為目標值的那 兩個 整數,並返回他們的陣列下標。
你可以假設每種輸入只會對應乙個答案。但是,你不能重複利用這個陣列中同樣的元素。
示例:給定 nums = [2, 7, 11, 15], target = 9
因為 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
看到這道題,不難理解,就是找出兩個值的和等於特定值的下標。
筆者沒有太多的想法,用python暴力法先實現一遍
上**(未通過-超出時間限制)
1class
solution:
2def
twosum(self, nums, target):
3"""
4:type nums: list[int]
5:type target: int
6:rtype: list[int]
7"""
8 result=
9for i in
range(len(nums)):
10for j in
range( len(nums)):
11if(nums[i]+nums[j]==target and i!=j):
1213
14break
15 aset=set(result) #
利用set無重複性消除重複新增
16 alist=list(aset)
1718
return
alist
1920
if__name__=="
__main__":
21 s=solution()
22 nums=[3,2,4]
23print(s.twosum(nums,6))
分析原因:**兩層for迴圈,時間複雜度為o(n^2),所以遇到資料量大的情況耗時較久。
優化:上**(通過-6800ms)擊敗20%
classsolution:
deftwosum(self, nums, target):
""":type nums: list[int]
:type target: int
:rtype: list[int]
"""result=
for i in
range(len(nums)):
for j in range(i+1, len(nums)): #
第i個和第i個之後的數值進行求和對比
if(nums[i]+nums[j]==target ): #
取消了i和j的對比
break
return
result
if__name__=="
__main__":
s=solution()
nums=[3,2,4]
print(s.twosum(nums,6))
解釋一下:
兩層for迴圈每乙個和其他元素進行求和的過程中會出現,相同的數操作兩遍的情況(比如i為下標3的數,j為下標6的數)當i和j的值互換(i=6,j=3)又求和進行操作,所以第二層迴圈再第i+1個開始,避免重複操作。這樣理論可以提高50%的效率。但是時間複雜度依舊為o(n^2)。所以比較耗時。
之後怎麼也想不到更好的方法,
1class
solution:23
deftwosum(self,nums,target):
4"""
5:param nums:
6:param target:
7:return:
8"""
9 sort=sorted(range(len(nums)),key=lambda
x:nums[x])
10 i=0
11 j=len(nums)-1
12 alist=
13while(nums[sort[i]]+nums[sort[j]]!=target):
14if(nums[sort[i]]+nums[sort[j]]>target): #
當最大的元素和最小的元素相加大於目標值
15 j-=1 #
最大元素前移乙個位置
16else: #
小於目標值時
17 i+=1 #
最小元素後移乙個位置
1819
20return
alist
2122
if__name__=="
__main__":
23 s=solution()
24 nums= [2, 1, 3, 8, 4]
25print(s.twosum(nums, 6))
說下設計思想:(首尾遞迴查詢)
首先第一部的排序有點技巧性,因為我們需要排序後才能首位遞進查詢,但是又需要返回排序前的下標。
所以根據list的值排序並且儲存的是list的下標。這樣就可以找到排序前的下標。
後面的**比較簡單,當和大於target時,最後乙個位置向前移,當和小於target時,第乙個位置向後移,
時間複雜度分析:
sorted()的複雜度為o(nlogn)
while()的複雜度為o(n)
所以複雜度為o(nlogn) 比之前的o(n^2)快了很多
然後在介紹乙個更快的方法 先上**(通過44ms)超過99%
1class
solution:
2def
twosum(self,nums,target):
3"""
4:param nums:
5:param target:
6:return:
7"""
8 dit={}
9for index,num in enumerate(nums): #
遍歷值和下標
10 sub=target-num
11if(sub in
dit):
12return [dit[sub],index] #
返回字典中的下標和index
13 dit[num]=index #
將num和index插入dit中
14return
none
15if
__name__=="
__main__":
16 s=solution()
17 nums= [2, 1, 3, 8, 4]
18print(s.twosum(nums, 4))
解釋下設計思想:
利用字典可以存放key和value。根據與target的差值查詢是否出現在字典中,如果有則返回下標,無則將index和num放入字典中並且遍歷下乙個,直到結束。
該方法for迴圈n次 減法操作1次,字典查詢是否存在最優情況下是1次,字典賦值語句1次
總的複雜度為o(n) 所以該方法特別快
posted @
2019-02-16 14:11
劍峰隨心 閱讀(
...)
編輯收藏
Python LeetCode 1 兩數之和
題目 給定乙個整數陣列 nums 和乙個目標值 target,請你在該陣列中找出和為目標值的那 兩個 整數,並返回他們的陣列下標。你可以假設每種輸入只會對應乙個答案。但是,你不能重複利用這個陣列中同樣的元素。示例 給定 nums 2,7,11,15 target 9 因為 nums 0 nums 1...
1 兩數之和 Python LeetCode
剛開始接觸演算法方面,好多都不懂,打算每刷一題就整理一下 給定乙個整數數列,找出其中和為特定值的那兩個數。你可以假設每個輸入都只會有一種答案,同樣的元素不能被重用。示例 給定 nums 2,7,11,15 target 9 因為 nums 0 nums 1 2 7 9 所以返回 0,1 解法一 剛開...
python leetcode 最大回文數
直接暴力求解時間超出,選取manacher演算法 class solution def longestpalindrome self,s t join s 前後插入 是為了防止越界,不需要進行邊界判斷 n len t p 0 n 每一處的回文半徑 c r 0 r為當前訪問到的最右邊的值,c為此時對稱...