242 有效的字母异位词
-
题意
- 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
- 示例 1: 输入: s = "anagram", t = "nagaram" 输出: true
- 示例 2: 输入: s = "rat", t = "car" 输出: false
- 说明: 你可以假设字符串只包含小写字母
-
思路
- 数组其实就是一个简单哈希表,而且这道题目中字符串只有小写字符,那么就可以定义一个数组,来记录字符串s里字符出现的次数;
- 字符a到字符z的ASCII是26个连续的数值,所以字符a映射为下标0,相应的字符z映射为下标25;hash[26]数组用于记录26个字母各自出现的次数,用s-t来判断有无重复;
class Solution {
public:
bool isAnagram(string s, string t) {
int hash[26] = { 0 };//hash表用于记录26个字母各自出现的次数,用s-t来判断有无重复
for (int i = 0; i < s.size(); i++) {
hash[s[i] - 'a']++;//对字符串s进行统计字母出现次数
}
for (int j = 0; j < t.size(); j++) {
hash[t[j] - 'a']--;//将字符串中出现的字母数减去字符串t中相同字母出现的次数,根据结果是否为零来判断是否为异位词
}
for (int i = 0; i < 26; i++) {
//如果出现hash != 0;说明两个字符串存在不同数目的相同字符,return false;
if (hash[i] != 0) return false;
}
return true;
}
};
349 两个数组的交集
-
题意
- 给定两个数组,编写一个函数来计算它们的交集
- 说明: 输出结果中的每个元素一定是唯一的。 我们可以不考虑输出结果的顺序
- 给定两个数组,编写一个函数来计算它们的交集
-
思路
- 输出结果每个元素是唯一的因此需要考虑去重,因此需要unordered_set即集合变量存储结果最后转换为vector返回;
- 遍历nums1中的元素转换为哈希值存储,再遍历nums2中的元素进行比较,将比较后重复的元素存储在unordered_set结果中返回;
- 此题的哈希数据结构可以选择unordered_set也可以选用数组,其区别在于直接使用set占用空间比数组大,且需要进行hash计算,速度比数组要慢;数组的数据是连续的,对于哈希值比较少,特别分散且跨度比较大的,使用数组就会造成空间的极大浪费;
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set <int>result;//定义一个集合用于避免元素重合
int hash[1005] = { 0 };
for (int i = 0; i < nums1.size(); i++) {
hash[nums1[i]] = 1;//nums1里面的数字出现过即记录对应出现过记为1;
}
for (int i = 0; i < nums2.size(); i++) {
//nums2中的数字在hash数组中也出现过即为1,为出现为0;若等式成立则既在nums1中出现过也在nums2中出现过
if (hash[nums2[i]] == 1) {
result.insert(nums2[i]);
}
}
return vector<int>(result.begin(), result.end());
}
};
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
-
思路
- 对每一个数取sum,使用取余得到每一个位数,使之平方;使用除10来更新位数;累加计算得到sum;
- 使用哈希记录每一次更新的sum值;sum = 1则return true;如果出现重复的sum则直接return false;
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set <int>result;//定义一个集合用于避免元素重合
int hash[1005] = { 0 };
for (int i = 0; i < nums1.size(); i++) {
hash[nums1[i]] = 1;//nums1里面的数字出现过即记录对应出现过记为1;
}
for (int i = 0; i < nums2.size(); i++) {
//nums2中的数字在hash数组中也出现过即为1,为出现为0;若等式成立则既在nums1中出现过也在nums2中出现过
if (hash[nums2[i]] == 1) {
result.insert(nums2[i]);
}
}
return vector<int>(result.begin(), result.end());
}
};
1 两数之和
-
题意
- 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
- 示例
- 给定 nums = [2, 7, 11, 15], target = 9
- 因为 nums[0] + nums[1] = 2 + 7 = 9
- 所以返回 [0, 1]
-
思路
- 使用map来存储元素的值与下标,用于查看当下元素的互补值(target-s)是否在map中已出现过
class Solution {
public:
int getsum(int n) {
int sum = 0;
while (n) {
sum += (n % 10) * (n % 10);
n /= 10;
}
return sum;
}
bool isHappy(int n) {
unordered_set<int>result;
int sum = getsum(n);
while (1) {
if (sum == 1)
return true;
else {
//发现在result里面出现了重复的数字,说明进无限循环了,直接false
if (result.find(sum) != result.end()) {
return false;
}
//如果没有重复,就存进去
else result.insert(sum);
}
sum = getsum(sum);//将sum更新
}
}
};
总结 && 碎碎念
来自1月2号的博客补写,拖了将近一个星期的……我有罪,元旦既然好好玩耍了,那现在就是恶犬刷题流了嗷~