给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
示例 1: 输入: s = "anagram", t = "nagaram" 输出: true
示例 2: 输入: s = "rat", t = "car" 输出: false
说明: 你可以假设字符串只包含小写字母。
创建一个长度为26的数组record,把字符映射到数组也就是哈希表的索引下标上(s[i] - 'a'),因为字符a到字符z的ASCII是26个连续的数值,所以字符a映射为下标0,相应的字符z映射为下标25。然后遍历第一个字符串记录每个字母出现次数,再遍历第二个字符串,对其中出现的字符映射哈希表索引上的数值再做-1的操作。
最后检查record数组中是否有不为零的值,代表不是异位词。
代码如下:
class Solution {
public:
bool isAnagram(string s, string t) {
int a[26] = {0};
for(int i = 0; i < s.size(); i++){
a[s[i] - 'a']++;
}
for(int j = 0; j < t.size(); j++){
a[t[j] - 'a']--;
}
for(int k = 0; k < 26; k++){
if(a[k] != 0) return false;
}
return true;
}
};
题意:给定两个数组,编写一个函数来计算它们的交集。
说明: 输出结果中的每个元素一定是唯一的。 我们可以不考虑输出结果的顺序。
将题中数组转化为unordered_set类型的set, 再创建一个用来存储结果的unordered_set类型的result,遍历第二个数组,在set中查找到相同元素再存储到 reult 中。
注意:使用数组来做哈希的题目,是因为题目都限制了数值的大小。
unordered_set类型数据插入新数据可用insert。
转化向量为unordered_set时和返回向量时都可用iterator(nums.begin(), nums.end())。
代码如下:
class Solution {
public:
vector intersection(vector& nums1, vector& nums2) {
unordered_set result_set;
unordered_set nums_set(nums1.begin(), nums1.end());
for(auto num : nums2){
if(nums_set.find(num) != nums_set.end()){
result_set.insert(num);
}
}
return vector(result_set.begin(), result_set.end());
}
};
编写一个算法来判断一个数 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
我刚开始只是想到用一个独立函数把n的各个位置上的数求出,然后放在循环中求各位置和。
代码如下:
class Solution {
public:
vector find_digits (int n){
vector digits;
while(n){
int a = n % 10;
digits.push_back(a);
n = n / 10;
}
return digits;
}
bool isHappy(int n) {
unordered_set sum;
while(n != 1){
vector digits = find_digits(n);
n = 0;
for(int i = 0; i < digits.size(); i++){
cout << digits[i] << endl;
n += digits[i]*digits[i];
}
if(sum.find(n) != sum.end()){
return false;
}
sum.insert(n);
}
return true;
}
};
但其实有更简便的方法可以建立一个求n各个数位上的平方和的函数。在判断是否是快乐数时要创建一个unordered_set变量来存储求过的和sum,这样就能在出现相同sum值时知道是进入循环了,返回false。
代码如下:
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 set;
while(1) {
int sum = getSum(n);
if (sum == 1) {
return true;
}
// 如果这个sum曾经出现过,说明已经陷入了无限循环了,立刻return false
if (set.find(sum) != set.end()) {
return false;
} else {
set.insert(sum);
}
n = sum;
}
}
};
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
此题需要用到unordered_map,因为不仅要记录元素的值还要记录它的下标。for循环遍历数组元素,找到 target-nums[i]对应值,返回当前元素下标和map中存储的下标。
注意:map中的存储结构为 {key:数据元素,value:数组元素对应的下表}。可用迭代器 iter->second 访问存储到map中的value。向map中插入对象可以用 insert(pair
代码如下:
class Solution {
public:
vector twoSum(vector& nums, int target) {
unordered_map store;
for(int i = 0; i < nums.size(); i++){
auto iter = store.find(target - nums[i]);
if(iter != store.end()){
return {iter->second, i};
}
store.insert(pair{nums[i], i});
}
return {};
}
};