代码随想录算法训练营第五天|242. 有效的字母异位词,349. 两个数组的交集 ,202. 快乐数 ,1. 两数之和 。
242. 有效的字母异位词
题目链接:242. 有效的字母异位词,难度:简单
【实现代码】
class Solution {
public:
bool isAnagram(string s, string t) {
if (s.size() != t.size()) {
return false;
}
int num[26] = {0};
for (int i = 0; i < s.size(); i++) {
num[s[i] - 'a']++;
num[t[i] - 'a']--;
}
for (int i = 0; i < 26; i++) {
if (num[i] != 0) {
return false;
}
}
return true;
}
};
【解题思路】
因为需要的数组长度较小(26个),所以考虑使用数组进行哈希求解,把字符映射到数组也就是哈希表的索引下标上。
再遍历 字符串s的时候,只需要将 s[i] - ‘a’ 所在的元素做+1 操作即可。
再遍历 字符串s的时候,对t中出现的字符映射哈希表索引上的数值再做-1的操作。
最后record数组如果有的元素不为零0,说明字符串s和t一定是谁多了字符或者谁少了字符,return false。最后如果record数组所有元素都为零0,说明字符串s和t是字母异位词,return true。
【总结】
【收获】熟悉了数组哈希的过程。
349. 两个数组的交集
题目链接:349. 两个数组的交集,难度:简单
【实现代码】
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> s(nums1.begin(), nums1.end());
unordered_set<int> result;
for (int i = 0; i < nums2.size(); i++) {
if (s.count(nums2[i]) != 0) {
result.insert(nums2[i]);
}
}
return vector<int>(result.begin(), result.end());
}
};
【解题思路】
将第一个数组存进无序的set容器s,对第二个数组进行遍历,并在s中查找是否有相同的值,有则存进结果的无序set。
【总结】
【第一想法】使用了数组哈希,浪费了空间。
【收获】熟悉了set哈希的过程。
202. 快乐数
题目链接:202. 快乐数,难度:简单
【实现代码】
class Solution {
public:
bool isHappy(int n) {
unordered_set<int> s;
int sum = 0;
int t= n;
while (1) {
while (n) {
t = n % 10;
sum += t * t;
n /= 10;
}
if (sum == 1) {
return true;
}
if (s.count(sum) != 0) {
return false;
}
s.insert(sum);
n = sum;
sum = 0;
}
}
};
【解题思路】
当求和sum重复时说明不是快乐数,所以使用无序set进行保存中间sum。
在评论里看到了双指针解法,真的是太妙了!代码如下:
//参考英文网站热评第一。这题可以用快慢指针的思想去做,有点类似于检测是否为环形链表那道题
//如果给定的数字最后会一直循环重复,那么快的指针(值)一定会追上慢的指针(值),也就是
//两者一定会相等。如果没有循环重复,那么最后快慢指针也会相等,且都等于1。
class Solution {
public boolean isHappy(int n) {
int fast=n;
int slow=n;
do{
slow=squareSum(slow);
fast=squareSum(fast);
fast=squareSum(fast);
}while(slow!=fast);
if(fast==1)
return true;
else return false;
}
private int squareSum(int m){
int squaresum=0;
while(m!=0){
squaresum+=(m%10)*(m%10);
m/=10;
}
return squaresum;
}
}
【总结】
【第一想法】刚开始没有想法,然后看到讲解中提到sum不重复时,就有了想法。
【收获】熟悉了set哈希的过程。
242. 有效的字母异位词
题目链接:1. 两数之和,难度:简单
【实现代码】
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> m;
vector<int> v;
for (int i = 0; i < nums.size(); i++) {
int tmp = target - nums[i];
if (m.count(tmp) == 1) {
v.push_back(m[tmp]);
v.push_back(i);
return v;
}
m.insert(make_pair(nums[i], i));
}
return v;
}
};
【解题思路】
使用map存进数组的中间值,当遍历数组时,将target-nums[i]的差值在map中查找。
需要注意的是map存的是<nums[i], i>。
【总结】
【第一想法】除了暴力求解外,因为是考察的哈希,有想到用set容器,但忘记了要返回下标。
【存在的问题】看到要使用map时,第一想法是把所有元素和下标插入到map,后来发现怎么也写不出来。应该是边遍历数组边存储到map。
【收获】熟悉了map哈希的过程。