1 Python刷
1.1 暴力法:時間O(n^2),空間O(1)
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
for i in range(len(nums)):
for j in range(i+1,len(nums)):
if nums[i] + nums[j] == target:
return[i,j]
break
1.2 一個for循環:時間O(n^2),空間O(1)
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
for i in range(len(nums)):
diff = target - nums[i]
if diff in nums: # 判斷差的數在不在列表裏
idx = nums.index(diff)
if idx != i:# 但是不能重複索引數字
return[i,idx]
break
1.3 不必每次搜索全部列表,搜索剩餘列表即可:時間O(n^2),空間O(1)
https://leetcode-cn.com/problems/two-sum/solution/xiao-bai-pythonji-chong-jie-fa-by-lao-la-rou-yue-j/
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
for i in range(len(nums)):
diff = target - nums[i]
temp = nums[i+1:]
if diff in temp: # 判斷差的數在不在剩餘列表裏
idx = temp.index(diff)
return[i,idx+i+1] # 記得idx是新列表中的索引,要還原到原列表
break
1.4 兩遍哈希:用字典模擬哈希表,通過字典去查詢:時間O(n),空間O(n)
爲了對運行時間複雜度進行優化,我們需要一種更有效的方法來檢查數組中是否存在目標元素。如果存在,我們需要找出它的索引。保持數組中的每個元素與其索引相互對應的最好方法是什麼?哈希表。https://leetcode-cn.com/problems/two-sum/solution/liang-shu-zhi-he-by-leetcode-2/
哈希表(散列表)是根據鍵(Key)直接訪問內存存儲位置的數據結構。根據鍵(Key)值將數據映射到內存中一個位置的函數稱爲哈希函數,根據哈希函數建立的記錄數據的表稱爲哈希表。
通過以空間換取速度的方式,我們可以將查找時間從 O(n)降低到 O(1)。哈希表正是爲此目的而構建的,它支持以近似恆定的時間O(1)進行快速查找。
一個簡單的實現使用了兩次迭代。在第一次迭代中,我們將每個元素的值和它的索引添加到表中。然後,在第二次迭代中,我們將檢查每個元素所對應的目標元素是否存在於表中。注意,該目標元素不能是元素本身!
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
hashmap = {} # 用字典代替哈希表功能
# 將每個元素的值和它的索引添加到哈希表
for idx, num in enumerate(nums):
# 注意這裏是原來的數值存成key鍵值,原來的索引存成字典的值
hashmap[num] = idx # 原列表中同一個數字num如果有重複出現,那麼構建字典過程中會被後出現的覆蓋
# 但是前面for循環中idx和num還是分別對應原始列表的索引和數值
'''e.g.1
nums = [2, 2, 4, 6] target=4
{2: 0}
{2: 1}
{2: 1, 4: 2}
{2: 1, 4: 2, 6: 3}
e.g.2
nums = [2, 1, 4, 6, 2]
{2: 0}
{2: 0, 1: 1}
{2: 0, 1: 1, 4: 2}
{2: 0, 1: 1, 4: 2, 6: 3}
{2: 4, 1: 1, 4: 2, 6: 3}
'''
for idx, num in enumerate(nums):
j = hashmap.get(target - num) #Python字典get()函數返回指定鍵的值,對於重複數字,一定是後一個的索引
if j is not None and j != idx:# 注意這裏,用原始列表的索引比較,就是重複數字的第一個的索引
return [idx, j]
1.5 一遍哈希:時間O(n),空間O(n)
在進行迭代並將元素插入到表中的同時,我們還會回過頭來檢查表中是否已經存在當前元素所對應的目標元素。如果它存在,那我們已經找到了對應解,並立即將其返回。
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
hashmap = {} # 用字典代替哈希表功能
for idx, num in enumerate(nums):
if hashmap.get(target - num) is not None:
return [hashmap.get(target - num), idx]# 如果哈希表中已經有過可以找到差值對應的,那麼一定是更靠前的,所以idx在後
break
hashmap[num] = idx # 第一遍hashmap爲空,故找不到跟第一個元素配對的數值,把第一元素加入字典
# 之後每次找不到對應的差的值才把它加入哈希表
2 用Python3刷
函數的輸入和輸出變量類型註解參考:https://zhuanlan.zhihu.com/p/37239021
class Solution:
#def twoSum(self, nums: List[int], target: int) -> List[int]:
def twoSum(self, nums, target):
hashmap = {} # 用字典代替哈希表功能
'''
for idx, num in enumerate(nums):
if num in hashmap:
return [hashmap[num], idx] # 如果哈希表中已經有過對應差值,那麼一定是更靠前的,所以idx在後
break
hashmap[target - num] = idx # 差值的哈希表,每次都是搜索差值是不是已經在哈希表中,如果在說明之前遍歷過了
# 1 3 2 7 target = 5
# 4 2 √
'''
for idx, num in enumerate(nums):
if target - num in hashmap:
return [hashmap[target - num], idx]
break
hashmap[num] = idx # 原始數值的哈希表
# 1 3 2 7 target = 5
# 1 3 √