1.背景
Leetcode專欄目的:希望給學習算法的朋友提供一些想法,也希望有大佬能夠通過評論提供寶貴的意見。
Leetcode專欄方式:將展示實現代碼的多種實現方式,並且對算法複雜度進行比較。由於筆者偏好,代碼全部使用python實現。
本期題目: https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/
2.解題方式
本題由展示三種解題方式
2.1 方法1:多重循環
這裏是使用雙重循環,即兩個搜索指針,判斷加和是否爲target,這裏第二個指針不需要從頭開始,只需要從i+1開始。算法複雜度O(n^2),是很多數據結構基礎不好的同學首選方案。
class Solution:
def twoSum(self, nums, target):
for i in range(len(nums)):
for j in range(i+1,len(nums)):
if nums[i] + nums[j] == target:
return [i,j]
2.2 方法2:列表搜索
列表搜索方法是新建立一個列表,對原列表進行遍歷,判斷target_num是否在新列表中。如果在則返回,如果不在將遍歷值加入新列表。這樣做有兩個好處,首先新列表與原列表的index是相同的;其次可以避免使用index優先返回第一個出現值的問題,例如 [3,2,3] target = 6,期望輸出[1,3],不採用新列表輸出[0, 0]。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
lt = []
for i in range(len(nums)):
target_num = target - nums[i]
if target_num in lt:
return [lt.index(target_num), i]
lt.append(nums[i])
2.3 方法3:hash搜索
這種方式和方法2相似,主要是改進了搜索方式,從而提高速度。先將代碼附上:
class Solution:
def twoSum(self, nums, target):
hashmap = {}
for index, num in enumerate(nums):
another_num = target - num
if another_num in hashmap:
return [hashmap[another_num], index]
hashmap[num] = index
return None
3. 總結
本次總結主要對方式3比方式2快進行解釋,即爲何字典的搜索速度比列表快。
- 爲什麼快:字典是hash類型
- 什麼是hash:哈希算法將任意長度的二進制值映射爲較短的固定長度的二進制值,這個小的二進制值稱爲哈希值。哈希值是一段數據唯一且極其緊湊的數值表示形式。如果散列一段明文而且哪怕只更改該段落的一個字母,隨後的哈希都將產生不同的值。要找到散列爲同一個值的兩個不同的輸入,在計算上是不可能的,所以數據的哈希值可以檢驗數據的完整性。一般用於快速查找和加密算法。
- python字典的hash邏輯:dict會把所有的key變成hash 表,然後將這個表進行排序,這樣,你通過data[key]去查data字典中一個key的時候,python會先把這個key hash成一個數字,然後拿這個數字到hash表中看沒有這個數字, 如果有,拿到這個key在hash表中的索引,拿到這個索引去與此key對應的value的內存地址那取值就可以了。
- 注意點:字典的快是建立在用空間換時間,即犧牲一定的空間換取查詢速度。從leetcode的報告上也能看出。