242.有效的字母异位词
题目
给定两个字符串 s
和 t
,编写一个函数来判断 t
是否是 s
的字母异位词。
注意:若 s
和 t
中每个字符出现的次数都相同,则称 s
和 t
互为字母异位词。
示例 1:
输入: s = "anagram", t = "nagaram" 输出: true
思考
初看题目,有相同字符和出现次数两个关键词,想用map将两个数组的关键词都存下来,然后遍历map来比较,感觉比较麻烦但思路OK,后面看讲解视频发现还可以用数组来做,因为关键是题目说明string里只有小写字母,则用 hash(s[i]-'a') 可以表示 s[i] 在长度为26的hash数组里出现的位置,随后将遍历两个string将hash数组++,--,最后判断hash数组里的元素是否全为0即可(其实我觉得用map的方法比较通用hhh)
代码
// 数组
class Solution {
public:
bool isAnagram(string s, string t)
{
int hash[26] = {0};
for (int i = 0; i < s.length(); i++)
hash[s[i] - 'a']++; // 因为字符串里只有a-z,那么字符串里每个字符-‘a’就是其在数组里的位置
for (int i = 0; i < t.length(); i++)
hash[t[i] - 'a']--;
for (auto i : hash) {
if (i != 0)
return false;
}
return true;
}
};
// map
class Solution {
public:
bool isAnagram(string s, string t)
{
unordered_map<char, int> maps, mapt;
for (auto c : s) {
if (maps.find(c) != maps.end())
maps[c]++;
else
maps.insert({c, 1});
}
for (auto c : t) {
if (maps.find(c) != maps.end())
mapt[c]++;
else
mapt.insert({c, 1});
}
if (maps.size() != mapt.size())
return false;
for (auto it : maps) {
if (mapt[it.first] != it.second || mapt.find(it.first) == mapt.end())
return false;
}
return true;
}
};
349. 两个数组的交集
题目
给定两个数组 nums1
和 nums2
,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2] 输出:[2]
思考
既然题目说说明每个元素一定是唯一的,那么用set再合适不过了,直接将nums1、nums2变成set,然后遍历nums2,如果nums1中发现有nums2的元素,则将该元素储存在一个结果vector中,需要注意的是vector变成set的方法是set(vector.begin(), vector.end()),在set中寻找value的方法是set.find(value) != set.end()
代码
class Solution {
public:
vector<int> intersection(vector<int> &nums1, vector<int> &nums2)
{
vector<int> result;
unordered_set<int> set1(nums1.begin(), nums1.end());
unordered_set<int> set2(nums2.begin(), nums2.end());
for (auto it : set2) {
if (set1.find(it) != set1.end())
result.push_back(it);
}
return result;
}
};
第202题. 快乐数
题目
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 True ;不是,则返回 False 。
示例:
输入:19
输出:true
解释:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1
思考
看到无限循环,立马反应过来需要用递归,但一直没明白这题和哈希有啥关系,因为当时想的是如果两次计算的结果一致,那么就return false,在while里存一个tmp,判断其是否等于sum就好,后看题解才发现原来是用set来做这操作,殊途同归,这题有两个关键:
1、一个数的每个位置上的数字,需要用n%10来表示
2、while循环条件是无限循环,即while(1),在循环里用条件来判断是否退出
代码
class Solution {
int calculate(int n) {
int sum = 0;
while(n > 0) {
int digit = n%10;
sum += pow(digit,2);
n/=10;
}
return sum;
}
public:
bool isHappy(int n) {
unordered_set<int> set1;//set的作用用来结束循环
while(1) {
int sum = calculate(n);
if(sum == 1) return true;
if(set1.find(sum) != set1.end()) return false;
else set1.insert(sum);
n = sum;
}
}
};
1. 两数之和
题目
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
思考
古老,古老,再古老的题目,所有刷过leetcode人都做过这题,两种方法,暴力和用map,暴力不多追谁,map方法的核心思想是遍历nums时用map.find(target-nums[i])的方法来判断是否有符合条件的数,如果有,将两个坐标返回,如果没有,map添加该元素和其位置。
代码
// map
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> map1;
for (int i = 0; i < nums.size(); i++) {
if(map1.find(target - nums[i]) != map1.end()) return {i, map1[target - nums[i]]};
else map1.insert({nums[i], i});
}
return {};
}
};
// 暴力
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int n = nums.size();
vector<int> res;
for (int i = 0; i < n; i++) {
for (int j = i+1; j < n; j++) {
if (nums[i] + nums[j] == target) {
res.insert(res.end(), {i,j});
}
}
}
return res;
}
};