文章目录
哈希表的查找效率O(1)
242. 有效的字母异位词
- char型a-z到int型数组下标s[i]-‘a’。
- for中字符串遍历结束s[i]!=‘\0’。
- 字符串长度s.length()。
class Solution {
public:
bool isAnagram(string s, string t) {
//统计字符串字符出现的次数,两个字符串所有字符出现的次数一致为有效的字母异位词
if(s.length() != t.length()) return false;
int statis[26] = {0};
for(int i = 0; s[i] != '\0'; i++){
//统计s中字符出现次数
statis[s[i] - 'a']++;
}
for(int i = 0; t[i] != '\0'; i++){
//统计t中字符出现次数
statis[t[i] - 'a']--;
}
for(int i = 0; i<26; i++){
//比较
if(statis[i] != 0) return false;
}
return true;
}
};
349 两个数组的交集
- 使用set不用数组和map。
- set的使用:unordered_set底层实现是哈希表、无序、内容不可重复、内容不可修改,查找和增删效率O(1)。
①初始化和赋值: unordered_set result(nums1.begin(), result.end());
②插入:result.insert(num);
③查找:result.find(num),找不到result.find(num) == result.end();效率O(1)。
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
//标记nums1中出现的数字,遍历nums2,查字符在nums1中出现则为交集。数字范围大稀疏度高,输出结果唯一,用set。不用数组和map
unordered_set<int> result_set;
//保存交集
unordered_set<int> nums1_set(nums1.begin(), nums1.end());
//nums1中int型保存在unordered_set中
for(int num:nums2){
//遍历nums2中int型数据
if(nums1_set.find(num) != nums1_set.end()){
//在nums1的set中找到了nums2中的字符
result_set.insert(num);
}
}
return vector<int>(result_set.begin(),result_set.end());
//类型转换,返回结果
}
};
202 快乐数
- 拆分数字得到每一位数字;
- 哈希表unordered_set查找结果是否重复。unordered_set查找效率O(1),适用于数据非整型,数据范围不固定。
- 问题抽象
图来自力扣官方题解
class Solution {
public:
bool isHappy(int n) {
//平方结果重复出现不是快乐数结束
//求解步骤:求n的每一位数字;结果1则true/查找重复false/不重复则记录
//2^31 = 2 147 483 648 10位,平方和最大数字1 999 999 999,范围1~730,循环次数有限,sum用int
int sum = 0;
unordered_set<int> result_set;//保存平方结果
while(true){
while(n!=0){
//n数位分离,时间复杂度logn
int a = n%10;
sum+=a*a;
n=n/10;
}
if(sum == 1) return true;
//结果1
else if(result_set.find(sum) != result_set.end()) return false;
//查找重复,false
else result_set.insert(sum);
//查找不重复,插入
n = sum;
sum = 0;
}
}
};
class Solution {
public:
int getNextStep(int n){
int sum = 0;
while(n){
int a = n%10;
sum += a*a;
n = n/10;
}
return sum;
}
bool isHappy(int n) {
int slow = n;
int fast = getNextStep(n);
while(fast != 1 && slow!=fast){
slow = getNextStep(slow);//在原来的位置走1步
fast = getNextStep(getNextStep(fast));//在原来位置走2步
}
return fast == 1;
//相遇处是1或者是其他
}
};
1 两数之和
两个数字 a+b= target。固定a,查找target - a是否存在,存在返回两个数的下标。
map插入:
map[“key”] = value;//插入相同key后者覆盖前者
map.insert(make_pair<>(“”, “”));//插入相同key前者保持不变
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
//既需要保存数组元素,也需要保存数组下标,两个重要信息,用set不可
//a+b = b+a
unordered_map <int, int> map;
for(int i = 0; i < nums.size(); i++){
auto tmp = map.find(target - nums[i]);
if(tmp != map.end()) return {tmp->second, i};
map.insert(pair<int, int>(nums[i], i));
}
return {};
}
};