242. 有效的字母异位词
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
提示:
1 <= s.length, t.length <= 5 * 104
s
和t
仅包含小写字母
解题思路:
1、暴力解法,双重for循环,时间复杂度O(n2);
2、哈希表。s.t仅包含小写字母,就可以用一个长为26的数组,记录每个字符串中每个字母出现的次数,然后对比这两个数组元素即可。为了节省空间,可以只定义一个长26值为0的数组,在遍历s的时候元素出现,数组对应位置++;遍历t的时候,数组对应位置++。最后如果该数组有某个元素不为0,则肯定s.t不是字母异位词。
class Solution {
public:
bool isAnagram(string s, string t) {
int i= 0;
int recode[26] = {0};
for(i=0;i<s.size();i++){
recode[s[i]-'a']++;
}
for(i=0;i<t.size();i++){
recode[t[i]-'a']--;
}
for(i=0;i<26;i++){
if(recode[i] != 0]){
return false;
}
}
return true;
}
};
342.两个数组的交集
给定两个数组 nums1
和 nums2
,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
解题思路
肯定还是用哈希表,两个数组长度小于1000,并且元素值也在0-1000之间,可以定义一个长为100的数组hush,用来对比nums1和nums2的元素值,如果nums1中含有值为num的元素,就将hash[num]赋值为1,在对比nums2的过程中,如果nums2中含有值为num的元素并且hashnum]已经为1,则num就是两数组共同拥有的元素,循环完之后返回。
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result_set; // 存放结果,之所以用set是为了给结果集去重
int hash[1005] = {0}; // 默认数值为0
for (int num : nums1) { // nums1中出现的字母在hash数组中做记录
hash[num] = 1;
}
for (int num : nums2) { // nums2中出现话,result记录
if (hash[num] == 1) {
result_set.insert(num);
}
}
return vector<int>(result_set.begin(), result_set.end());
}
};
202.快乐数
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
解题思路:
这道题目看上去貌似一道数学问题,其实并不是!
题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!
正如:关于哈希表,你该了解这些! (opens new window)中所说,当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了。
所以这道题目使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。
判断sum是否重复出现就可以使用unordered_set。
还有一个难点就是求和的过程,如果对取数值各个位上的单数操作不熟悉的话,做这道题也会比较艰难。
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> 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;
}
}
};
1. 两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
解题思路:
方法一:暴力解法
一个数组中,找出两个元素值为target的元素下标,双重for循环即可,第一层i=0,第二层j=i+1。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int i = 0,j = 0;
for(i=0;i<nums.size();i++){
for(j=i+1;j<nums.size();j++){
if(nums[i]+nums[j] == target)
return {i,j};
}
}
return {};
}
};
方法二:哈希表
定义一个map,key值放数组元素值,value放下标,遍历一遍数组就可以完成,遍历过程中寻找map中是否有target-nums[i]的key,如果有,返回i及该map的value,如果没有就将这个元素加入到map
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
std::unordered_map<int,int>map;
for(int i=0;i<nums.size();i++){
auto item = map.find(target-nums[i]);
if (item != map.end())
return {item->second,i} ;
map.insert(pair<int,int>(nums[i],i));
}
return {};
}
};