今日任务
哈希表理论基础
242. 有效的字母异位词
方法一:哈希表
t i m e : O ( n ) , s p a c e : O ( n ) time: O(n), space: O(n) time:O(n),space:O(n)
使用 unordered_map
版本
class Solution {
public:
bool isAnagram(string s, string t) {
if (s.size() != t.size()) return false;
unordered_map<char, int> charsMap, chartMap;
for (int i = 0; i < s.size(); ++i) {
!charsMap.count(s[i]) && (charsMap[s[i]] = 0);
++charsMap[s[i]];
!chartMap.count(t[i]) && (chartMap[t[i]] = 0);
++chartMap[t[i]];
}
if (charsMap.size() != chartMap.size()) return false;
for (auto it : charsMap) {
if (chartMap[it.first] != it.second) return false;
}
return true;
}
};
使用数组版本
class Solution {
public:
// 直接用数组
bool isAnagram(string s, string t) {
if (s.size() != t.size()) return false;
int check1['z' + 1] = {0}, check2['z' + 1] = {0};
int len = s.size();
for (int i = 0; i < len; ++i) {
++check1[s[i]], ++check2[t[i]];
}
// 如果s.size()过长那么可以选择直接遍历'a' ~ 'z'
for (auto c : t) {
if (check1[c] != check2[c]) return false;
}
return true;
}
};
349. 两个数组的交集
方法一:哈希表
t i m e : O ( n ) , s p a c e : O ( n ) time: O(n), space: O(n) time:O(n),space:O(n)
由于结果中每个元素只输出一次,所以如果一个元素已经被从哈希表中check出来了,记得删除
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> check1;
vector<int> unionNums;
for (auto i : nums1) if (!check1.count(i)) check1.insert(i);
for (auto i : nums2) {
if (check1.count(i)) {
unionNums.push_back(i);
check1.erase(i);
}
}
return unionNums;
}
};
用 unordered_set
记录结果方便去重,最后返回vector<int>(res.begin(), res.end())
就不用删除了
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> res;
int check[1005] = {0}; // 用来记录nums1中出现的数
for (auto i : nums1) check[i] = 1;
for (auto i : nums2) {
if (check[i]) res.insert(i);
}
return vector<int>(res.begin(), res.end()); // O(n)
}
};
202. 快乐数
方法一:哈希表
class Solution {
public:
// bitSum: time: O(1)
int bitSum(int num) {
int res = 0;
while (num) {
res += pow(num % 10, 2);
num /= 10;
}
return res;
}
// isHappy: time: O(n)
bool isHappy(int n) {
unordered_set<int> ocurred;
while (n != 1) {
if (ocurred.count(n)) return false;
ocurred.insert(n);
n = bitSum(n);
}
return true;
}
};
方法二:快慢指针
如果陷入循环那么数据会成环
![image-20230814200203991](https://i-blog.csdnimg.cn/blog_migrate/7a4bbf6d422d8523034d2775be605c0a.png)
class Solution {
public:
int bitSquareSum(int num) {
int res = 0;
while (num) {
res += pow(num % 10, 2);
num /= 10;
}
return res;
}
bool isHappy(int n) {
int slow = n, fast = n;
do {
slow = bitSquareSum(slow);
fast = bitSquareSum(bitSquareSum(fast));
} while (slow != fast);
return slow == 1;
}
};
1. 两数之和
方法一:哈希表
t i m e : O ( n ) , s p a c e : O ( n ) time: O(n), space: O(n) time:O(n),space:O(n)
注意,本题不能是返回相同下标(也就是不能 2 * nums[i] == target
)
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> indexOf; // deduct[x] = target - x;
int len = nums.size();
for (int i = 0; i < len; ++i) {
indexOf[nums[i]] = i;
}
for (int i = 0; i < len; ++i) {
if (indexOf.count(target - nums[i]) && (i != indexOf[target - nums[i]])) return {i, indexOf[target - nums[i]]};
}
return {};
}
};
方法二:暴力
t i m e : O ( n 2 ) , s p a c e : O ( n ) time: O(n^2), space: O(n) time:O(n2),space:O(n)
看到两年前的提交想起来幼稚的自己
![image-20230814203847037](https://i-blog.csdnimg.cn/blog_migrate/8dc1f83076fb42538da21e8836a68e4a.png)
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
for (int i = 0; i < nums.size() - 1; i++) {
for (int j = i + 1; j < nums.size(); j++) {
if (nums[i] + nums[j] == target) {
return {i, j};
}
}
}
return {};
}
};