碎碎念:最近有点懈怠了感觉,继续加油。
参考:代码随想录
哈希表最擅长解决的问题:给你一个元素判断这个元素是否出现过。
如果数值nums[i]最大值很大、如果数值不是很大,但是nums[i]数值分布很分散,一般用set。
242. 有效的字母异位词
题目链接
思想
用数组模拟哈希表,判断一个元素在哈希表中是否出现过。
在s中出现过,会使得对应位置上的值为1,如果字母在t中也出现过,会使得对应位置上的值从1变为0,那么如果是有效的字母异位词,处理过后所有位置的值都是0,返回true即可,否则返回false。
题解
class Solution {
public:
bool isAnagram(string s, string t) {
int record[26] = {0};
for (int i = 0; i < s.size(); i++) {
record[s[i] - 'a'] ++;
}
for (int i = 0; i < t.size(); i++) {
record[t[i] - '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
for c in s:
record[ord(c) - ord("a")] += 1
for c in t:
record[ord(c) - ord("a")] -= 1
for i in range(26):
if record[i] != 0:
return False
return True
反思
ord() 是一个内置函数,用于返回表示单个字符的Unicode代码点的整数。
349. 两个数组的交集
题目链接
思想
处理nums1转换为哈希表的形式,遍历nums2的元素,查每个元素是否出现在哈希表中。如果出现过,就把这个元素放到result集合中。
题解
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result;
unordered_set<int> nums_set(nums1.begin(), nums1.end());
for (int i = 0; i < nums2.size(); i++) {
if(nums_set.find(nums2[i]) != nums_set.end()) {
result.insert(nums2[i]);
}
}
return vector<int>(result.begin(), result.end());
}
};
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
nums1 = set(nums1) # set主要是去重
nums2 = set(nums2)
record = [0] * 1001
res = []
for num in nums1:
record[num] += 1
for num in nums2:
if record[num] != 0:
res.append(num)
return res
反思
unordered_set可以做去重的操作,所以result用unordered_set。
注意熟悉用set的写法。
202. 快乐数
题目链接
思想
如果sum会无线循环,也就意味着sum会重复出现,那么可以用哈希表来快速判断一个元素是否重复出现。
题解
class Solution {
public:
int getSum(int n) {
int sum = 0;
int digit;
while (n) {
digit = n % 10;
n /= 10;
sum += digit * digit;
}
return sum;
}
bool isHappy(int n) {
unordered_set<int> set;
while (n != 1 && set.find(n) == set.end()) {
set.insert(n);
n = getSum(n);
}
return n == 1;
}
};
class Solution:
def isHappy(self, n: int) -> bool:
record = set()
while n != 1 and n not in record:
record.add(n)
n = self.get_num(n)
return n == 1
def get_num(self, n):
sum = 0
while n > 0:
n, digit = divmod(n, 10)
sum += digit ** 2
return sum
反思
注意C++判断一个元素是否在哈希表中的写法。
注意取数值各个位上的单操作数的写法。
1. 两数之和
题目链接
思想
核心是要判断一个元素是否遍历过,这里“一个元素”指的是和当前元素相加等于target的那个数字,比如target是10,当前遍历到6,这个“一个元素”指的就是4,我们要看4是否遍历过。这个可以用哈希表做一个很快的判断,所以这题的核心就是用哈希表。
本题的元素和下表都要知道,所以考虑使用map。我们想要快速查找元素是否在map里,所以元素作为key,下标作为value。
题解
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map <int, int> map;
for (int i = 0; i <nums.size(); i++) {
auto iter = map.find(target - nums[i]);
if (iter != map.end()) return {iter->second, i};
map.insert(pair<int, int>(nums[i], i));
}
return {};
}
};
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
nums_set = set()
for index, num in enumerate(nums):
compliment = target - num
if compliment in nums_set:
return [nums.index(compliment), index]
nums_set.add(num)
反思
见思想,重点。