哈希表是一种在时间和空间上做权衡的数据结构,通过哈希函数将键映射到数组索引,实现O(1)平均时间复杂度的查找、插入、删除操作。
给定两个字符串 s 和 t,判断 t 是否是 s 的字母异位词。
数组就是最简单的哈希表,当数据范围有限且连续时,数组是最优选择。
class Solution {
public:
bool isAnagram(string s, string t) {
int record[26] = {0};
// 统计s中字符出现次数
for (char c : s) {
record[c - 'a']++;
}
// 减去t中字符出现次数
for (char c : t) {
record[c - 'a']--;
}
// 检查是否所有字符都平衡
for (int i = 0; i < 26; i++) {
if (record[i] != 0) {
return false;
}
}
return true;
}
};
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
record = [0] * 26
# 统计s中字符出现次数
for c in s:
record[ord(c) - ord('a')] += 1
# 减去t中字符出现次数
for c in t:
record[ord(c) - ord('a')] -= 1
# 检查是否所有字符都平衡
return all(count == 0 for count in record)
优势分析:
class Solution {
public:
bool isAnagram(string s, string t) {
if (s.length() != t.length()) return false;
sort(s.begin(), s.end());
sort(t.begin(), t.end());
return s == t;
}
};
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
return sorted(s) == sorted(t)
优势分析:
class Solution {
public:
bool isAnagram(string s, string t) {
if (s.length() != t.length()) return false;
unordered_map<char, int> count;
for (char c : s) {
count[c]++;
}
for (char c : t) {
count[c]--;
if (count[c] < 0) return false;
}
return true;
}
};
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
if len(s) != len(t):
return False
count = {}
for c in s:
count[c] = count.get(c, 0) + 1
for c in t:
count[c] = count.get(c, 0) - 1
if count[c] < 0:
return False
return True
优势分析:
给定两个数组,计算它们的交集。
当数据范围不固定时,需要使用set或map作为哈希表。
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> nums_set(nums1.begin(), nums1.end());
unordered_set<int> result_set;
for (int num : nums2) {
if (nums_set.find(num) != nums_set.end()) {
result_set.insert(num);
}
}
return vector<int>(result_set.begin(), result_set.end());
}
};
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
# 使用集合的交集操作
return list(set(nums1) & set(nums2))
优势分析:
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result_set;
int hash[1001] = {0}; // 假设数据范围在1000以内
for (int num : nums1) {
hash[num] = 1;
}
for (int num : nums2) {
if (hash[num] == 1) {
result_set.insert(num);
}
}
return vector<int>(result_set.begin(), result_set.end());
}
};
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
# 假设数据范围在1000以内
hash_set = set()
hash_array = [0] * 1001
for num in nums1:
hash_array[num] = 1
for num in nums2:
if hash_array[num] == 1:
hash_set.add(num)
return list(hash_set)
优势分析:
判断一个数是否为快乐数(各位数字平方和最终等于1)。
使用哈希表检测循环,避免无限循环。
class Solution {
public:
int getSum(int n) {
int sum = 0;
while (n) {
sum += (n % 10) * (n % 10);
n /= 10;
}
return sum;
}
bool isHappy(int n) {
unordered_set<int> seen;
while (n != 1) {
n = getSum(n);
if (seen.find(n) != seen.end()) {
return false; // 检测到循环
}
seen.insert(n);
}
return true;
}
};
class Solution:
def isHappy(self, n: int) -> bool:
seen = set()
while n != 1:
n = sum(int(digit) ** 2 for digit in str(n))
if n in seen:
return False # 检测到循环
seen.add(n)
return True
优势分析:
class Solution {
public:
int getSum(int n) {
int sum = 0;
while (n) {
sum += (n % 10) * (n % 10);
n /= 10;
}
return sum;
}
bool isHappy(int n) {
int slow = n, fast = n;
do {
slow = getSum(slow);
fast = getSum(getSum(fast));
} while (slow != fast);
return slow == 1;
}
};
class Solution:
def isHappy(self, n: int) -> bool:
def get_sum(num):
return sum(int(digit) ** 2 for digit in str(num))
slow = fast = n
while True:
slow = get_sum(slow)
fast = get_sum(get_sum(fast))
if slow == fast:
break
return slow == 1
优势分析:
在数组中找出两个数,使它们的和等于目标值。
使用map记录已遍历的元素及其下标,实现一次遍历解决。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> map;
for (int i = 0; i < nums.size(); i++) {
int complement = target - nums[i];
if (map.find(complement) != map.end()) {
return {map[complement], i};
}
map[nums[i]] = i;
}
return {};
}
};
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
seen = {}
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [seen[complement], i]
seen[num] = i
return []
优势分析:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
for (int i = 0; i < nums.size(); i++) {
for (int j = i + 1; j < nums.size(); j++) {
if (nums[i] + nums[j] == target) {
return {i, j};
}
}
}
return {};
}
};
class Solution:
def twoSum(self, nums: List[int], target: int) -> 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]
return []
优势分析:
给定四个数组,计算有多少个元组使A[i] + B[j] + C[k] + D[l] = 0。
将四数之和转化为两数之和,使用map记录A+B的和及其出现次数。
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
unordered_map<int, int> umap;
// 统计A+B的和及其出现次数
for (int a : A) {
for (int b : B) {
umap[a + b]++;
}
}
int count = 0;
// 查找-(C+D)是否在map中
for (int c : C) {
for (int d : D) {
if (umap.find(-(c + d)) != umap.end()) {
count += umap[-(c + d)];
}
}
}
return count;
}
};
class Solution:
def fourSumCount(self, nums1: List[int], nums2: List[int],
nums3: List[int], nums4: List[int]) -> int:
from collections import defaultdict
count_map = defaultdict(int)
# 统计nums1+nums2的和及其出现次数
for n1 in nums1:
for n2 in nums2:
count_map[n1 + n2] += 1
count = 0
# 查找-(nums3+nums4)是否在map中
for n3 in nums3: