目錄
1.?啥是哈希表?
2.?啥時候用哈希表?
2.1 存在性檢查?→?集合Set
2.2?鍵值映射?→?字典Dict
2.3?頻率統計?→?Dict?or?Counter
3.?LeetCode
3.1?集合
(1)2215?找出兩數組的不同
(2)1207?獨一無二的出現次數
(3)128?最長連續序列
3.2?字典
(1)49?字母異位詞分組
(2)2352?相等行列對
(3)1 兩數之和
?3.3?統計元素出現頻率
(1)1657?確定兩個字符串是否接近
1.?啥是哈希表?
(1)哈希表(Hash Table)是一種通過??鍵值對??(key-value pairs)存儲數據的數據結構,核心是使用??哈希函數??(hash function)將鍵(key)映射到數組的特定位置。
(2)在Python中,哈希表通常有兩種形式:set和dict。
-
set: 存儲唯一元素的集合,不支持鍵值對。
-
dict: 存儲鍵值對,鍵是唯一的。
2.?啥時候用哈希表?
快速查找:如判斷元素是否在集合中(O(1)時間復雜度)。
去重:如獲取唯一元素集合。
計數:利用字典統計元素出現頻率。
映射關系:存儲鍵值對,如緩存、數據庫索引等。
集合運算:如求交集、并集、差集等。
2.1 存在性檢查?→?集合Set
(1)應用場景:
判斷元素是否存在
去重處理
唯一性驗證
交/并/差集運算
(2)實現模板:
def existence_check(data):# 1. 創建哈希集合seen = set()result = []# 2. 遍歷數據for item in data:# 3. 檢查或添加if item not in seen: # 存在性檢查result.append(item)seen.add(item) # 記錄訪問# 4. 返回結果return result
2.2?鍵值映射?→?字典Dict
(1)應用場景:
索引-值映射(如兩數之和)
分組統計(如字母異位詞)
緩存實現
頻率統計
(2)實現模板:
def value_mapping(data):# 1. 創建哈希字典mapping = {}# 2. 遍歷數據for item in data:# 3. 檢查或更新映射if item not in mapping: # 首次出現mapping[item] = ... # 初始化值else:mapping[item] = ... # 更新值# 4. 返回結果return mapping
2.3?頻率統計?→?Dict?or?Counter
(1)應用場景:
元素計數
Top K 問題
頻率唯一性檢查
字謎判斷
(2)實現模板:
from collections import Counterdef frequency_analysis(data):# 方法1:手動統計freq = {}for item in data:freq[item] = freq.get(item, 0) + 1 # 安全獲取更新# 方法2:Counter簡化版freq = Counter(data)# 3. 處理結果(如找頻率唯一)unique_counts = set()for count in freq.values():if count in unique_counts:return Falseunique_counts.add(count)return True
3.?LeetCode
3.1?集合
(1)2215?找出兩數組的不同
給你兩個下標從?0
?開始的整數數組?nums1
?和?nums2
?,請你返回一個長度為?2
?的列表?answer
?,其中:answer[0]
?是?nums1
?中所有?不?存在于?nums2
?中的?不同?整數組成的列表;answer[1]
?是?nums2
?中所有?不?存在于?nums1
?中的?不同?整數組成的列表。
class Solution(object):def findDifference(self, nums1, nums2):""":type nums1: List[int]:type nums2: List[int]:rtype: List[List[int]]"""set1 = set(nums1)set2 = set(nums2)result1 = list(set1-set2) ## 求差集result2 = list(set2-set1)return [result1, result2]
(2)1207?獨一無二的出現次數
給你一個整數數組?arr
,如果每個數的出現次數都是獨一無二的,就返回?true
;否則返回?false
class Solution(object):def uniqueOccurrences(self, arr):""":type arr: List[int]:rtype: bool"""count = dict()seen = set()for num in arr:## 從字典count中獲取鍵num對應的值。如果鍵num不存在,則返回默認值0count[num] = count.get(num,0) + 1 for value in count.values():if value in seen:return Falseseen.add(value)return True
(3)128?最長連續序列
給定一個未排序的整數數組?nums
?,找出數字連續的最長序列(不要求序列元素在原數組中連續)的長度。請你設計并實現時間復雜度為?O(n)
?的算法解決此問題。
從集合中的隨機num出發,查看其左(lower)右(higher)最多延伸到哪里。
如果lower(num-1)存在,那么:
①num_set.remove(lower):從集合set中移除當前lower,因為如果從新的num開始查找,則說明當前的lower是和之前的num連續,不可能和新num連續
②length++:當前連續序列長度更新
③lower--:繼續找,看有沒有更小的連續
class Solution(object):def longestConsecutive(self, nums):""":type nums: List[int]:rtype: int"""if not nums:return 0num_set = set(nums)max_len = 0while num_set:num = num_set.pop() # 隨機取一個元素length = 1lower = num-1 ## 向更小方向擴展while lower:num_set.remove(lower) length += 1lower -= 1higher = num+1 ## 向更大方向擴展while higher:num_set.remove(higher)length += 1higher += 1max_len = max(max_len, length)return max_len
3.2?字典
(1)49?字母異位詞分組
給你一個字符串數組,請你將字母異位詞(通過重新排列不同單詞或短語的字母而形成的單詞或短語,并使用所有原字母一次)組合在一起。可以按任意順序返回結果列表。
輸入:?strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
輸出:?[["bat"],["nat","tan"],["ate","eat","tea"]]
字母異位詞:包含的字母及其個數完全相同?→?排序后應是完全相同的字符串
創建列表類型的字典,字典的?key?是排好序的字符串,value?是對應的原字符串組成的?
(2)2352?相等行列對
給你一個下標從?0?開始、大小為?n x n
?的整數矩陣?grid
?,返回滿足?Ri
?行和?Cj
?列相等的行列對?(Ri, Cj)
?的數目。如果行和列以相同的順序包含相同的元素(即相等的數組),則認為二者是相等的。
??1.預處理所有行??:將每一行轉換為可哈希對象(如元組),存儲到字典中記錄出現次數
2.??處理列并匹配??:遍歷每一列,將其轉換為相同格式的可哈希對象,檢查是否在行字典中存在,存在則累加次數
from collections import defaultdict
class Solution(object):def equalPairs(self, grid):""":type grid: List[List[int]]:rtype: int"""n=len(grid)row_dict = defaultdict(int)for i in range(n):row_tuple = tuple(grid[i]) ## 將每一行轉換為元組(可哈希對象)row_dict[row_tuple] += 1 ## 記錄每個行元組出現的次數count = 0for j in range(n):## 對每一列:提取各行的第 j 個元素形成元組col_tuple = tuple(grid[i][j] for i in range(n)) if col_tuple in row_dict: ## 檢查列元組是否在行字典中count += row_dict[col_tuple] ## 如果存在,累加該行元組的出現次數return count
(3)1 兩數之和
給定一個整數數組?nums
?和一個整數目標值?target
,請你在該數組中找出?和為目標值?target
? 的那?兩個?整數,并返回它們的數組下標。你可以假設每種輸入只會對應一個答案,并且你不能使用兩次相同的元素。你可以按任意順序返回答案。
兩數之和?→?根據當前 num 找其和 target 的差值是否存在于數組中
返回的是下標?→?通過哈希表 {num:index}實現,讓數組數值和下標一一對應
class Solution(object):def twoSum(self, nums, target):""":type nums: List[int]:type target: int:rtype: List[int]"""num_map = {} ## 創建哈希表{num:index}for i, num in enumerate(nums):x = target - nums[i]if x in num_map: ## 要找的數在哈希表里,直接返回對應索引return [i, num_map[x]]num_map[num] = i ## 將當前num和其index加入哈希表
?3.3?統計元素出現頻率
(1)1657?確定兩個字符串是否接近
如果可以使用以下操作從一個字符串得到另一個字符串,則認為兩個字符串?接近?:
你可以根據需要對任意一個字符串多次使用這兩種操作。給你兩個字符串,word1
?和?word2
?。如果?word1
?和?word2
?接近?,就返回?true
?;否則,返回?false
?。
兩個字符串接近的條件:
兩個字符串的長度必須相同(因為操作不會改變長度)。
兩個字符串包含的字符種類必須相同(即字符集合相同)。
兩個字符串的字符頻率排序后必須相同(因為操作2允許我們重新分配字符,所以只要頻率的集合相同,就可以通過操作2將一種字符的頻率分配給另一種字符)。
from collections import Counter
class Solution(object):def closeStrings(self, word1, word2):""":type word1: str:type word2: str:rtype: bool"""if len(word1) != len(word2):return Falseif set(word1) != set(word2):return Falsecount1 = Counter(word1) ## 使用Counter統計字符頻率count2 = Counter(word2)if sorted(count1.values()) == sorted(count2.values()):return Trueelse: return False