代码随想录第六天| 242.有效的字母异位词 、349. 两个数组的交集 、202. 快乐数、1. 两数之和
讲解文章,参考代码随想录:https://programmercarl.com/0001.%E4%B8%A4%E6%95%B0%E4%B9%8B%E5%92%8C.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE
y总视频讲解:https://www.acwing.com/activity
242.有效的字母异位词
先看代码:
class Solution {
public:
bool isAnagram(string s, string t) {
unordered_map<char,int> a,b;
for(auto c:s) a[c]++;
for(auto c:t) b[c]++;
return a == b;
}
};
这道题目就是对map的考察,对于一个字符串并且和出现次数关联起来的,基本会用map。知道使用map,这道题目就会很简单,就是对两个字符串分别统计计数,然后比较,这里的容器是支持比较运算符的。
349. 两个数组的交集
先看代码:
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> S;
for(auto n:nums1) S.insert(n);
vector<int> res;
for(auto x:nums2)
{
if(S.count(x))
{
res.push_back(x);
S.erase(x);
}
}
return res;
}
};
首先题目里交代了,输出唯一,当输入不唯一,但是要求输出唯一,这个时候就很容易想到使用set,因为set的特性就是保证集合中没有重复的数值。
由于返回值是vector,所以输出不能是set,可以把输入变成set。
这道题的思路就是遍历其中一个数组,然后查看另一个数组里面有没有类似的,有的话就加进答案数组,并且要在set里面删除该值。
为什么找到了,加进答案数组还要删除这个值?不删除可以吗?
回答:不删除不可以,因为比如去查找的数组里面有两个“2”,第一次发现了,如果不删除set里面的“2”,第二次再次发现“2”的时候还会将2加进答案数组,这样输出就变成不唯一了。
202. 快乐数
先看使用哈希的代码:
class Solution {
public:
int get(int x)
{
int res = 0;
while(x)
{
res += (x % 10) * (x % 10);
x /= 10;
}
return res;
}
bool isHappy(int n) {
unordered_set<int> S;
while(1)
{
int sum = get(n);
if(sum == 1) return true;
if(S.find(sum) != S.end()) return false; //这里S.find()是查找指定的值,如果找到返回该元素迭代器,没找到就指向容器的结束位置
else S.insert(sum);
n = sum;
}
}
};
双指针代码:
class Solution {
public:
int get(int x)
{
int res = 0;
while(x)
{
res += (x % 10) * (x % 10);
x /= 10;
}
return res;
}
bool isHappy(int n) {
int fast = get(n),slow = n;
while(fast != slow)
{
fast = get(get(fast));
slow = get(slow);
}
return fast == 1;
}
};
这道题目比较有意思,首先是使用hash的,这个的思路是表明了的,每次算出sum,先看是否为一,如果不是,就找set里面还有没有存储这个sum,没有的话加进去,有的话说明出现先循环了,且循环中没有1,那就返回fasle
会不会有朋友说如果set里面加不怎么办?
根据题目中n的范围,我们可以假设n为一个9999999999的数,那么最后的sum的值是9910 = 810,也就是说,我n怎么变也就在这810中情况中,当我set的里面最坏加到811个数的时候就有重复的了,抽屉原理。
然后继续,这样的话我们就知道n一直这么算下去有下面情况:
- 出现了循环,但是循环里没有1;
- 出现了循环,循环里有1;
- 就只有1,本身,1是自成环。
所以还记得前面环形链表||的题目吗?双指针,fast和slow,这里比那个简单,就看fast和slow相遇的时候有没有1,就可以了。
1. 两数之和
暴力代码:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
for(int i = 0;i < nums.size();i++)
{
int res = target - nums[i];
for(int j = 0;j < nums.size();j++)
{
if(j != i && res == nums[j])
return {i,j};
}
}
return {};
}
};
使用map:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> heap;
for(int i = 0;i < nums.size();i++)
{
int res = target - nums[i];
if(heap.count(res)) return {heap[res],i};
heap[nums[i]] = i;
}
return {};
}
};
这道题目就是用target减去一个数,然后在另一个数组里面找,暴力也可以。
总结
今天回顾了哈希,也学会了一些模板的方法,比find(),end(),count(),count()就是返回这个值在容器中个数,个数为0,说明不再容器中。