242 有效的字母异位词
思路就是先比较两个长度,长度不一样肯定false
两个哈希表,每个string按照字母分别入表。
再遍历字符串s的每个字母,查询该字母在t表中出现次数是否与s表中出现次数相同。
很简单 一次AC
上代码:
class Solution {
public:
bool isAnagram(string s, string t) {
int s_len=s.size();
int t_len=t.size();
if(s_len!=t_len) return false;
unordered_map<char,int> smap;
unordered_map<char,int> tmap;
for(int i=0;i<s_len;++i){
if(smap.count(s[i])==0){
smap.insert({s[i],1});
}
else{
auto it=smap.find(s[i]);
++(it->second);
}
if(tmap.count(t[i])==0){
tmap.insert({t[i],1});
}
else{
auto it=tmap.find(t[i]);
++(it->second);
}
}
for(int i=0;i<s_len;++i){
if(tmap.count(s[i])==0) return false;
else if((tmap.find(s[i])->second)!=(smap.find(s[i])->second)) return false;
}
return true;
}
};
349. 两个数组的交集
先上代码,哈希表很容易就能做,思路不多赘述
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
vector<int> result;
int n1=nums1.size();
int n2=nums2.size();
unordered_set<int> mySet;
for(int i=0;i<n1;++i){
if(mySet.count(nums1[i])==0){
mySet.insert(nums1[i]);
}
}
for(int i=0;i<n2;++i){
if(mySet.count(nums2[i])!=0){
result.push_back(nums2[i]);
mySet.erase(nums2[i]);
}
}
return result;
}
};
由这道题小小地发现了一件事
就是现在的刷题主题是哈希表
所以我在解题的时候很容易就往哈希表上想,然后只用哈希表来做,做出来就完事了。
这道题我看了眼力扣的题解,发现题解给了两种其他方法(虽然时间复杂度都不如哈希表)
但是也可以提供一些其他的思路?尤其是想要减小空间复杂度的情况下。只用哈希表做完相当于把自己的思路限制住了。
(题解给的另一种算法感觉也很好,排序+双指针,指针指向相同就取值,时间复杂度是O(mlogm+nlogn))暴力法太笨了,就不提了。
202 快乐数
一开始不知道哪里可以用到哈希表,注意力全都在如何把数的每位取下来和如何构建一个循环当sum为1的时候返回true
但是看到题中说可能会有无限循环的情况,一下子不知道怎么判断这种情况
看了一下题解,把每次sum存入哈希表,循环中如果出现相同的sum证明进入了无限循环。
一切清楚了(把数的每位取下来稍微有点绕,我是另外写了一个函数然后从个位开始取,取完就减掉再除以10,直到为0)
上代码,
class Solution {
public:
bool isHappy(int n) {
unordered_set<int> mySet;
mySet.insert(n);
if(n==1) return true;
int result=n;
while(result!=1){
result=getSum(result);
if(mySet.count(result)!=0) return false;
else mySet.insert(result);
}
return true;
}
int getSum(int n){
int s=n;
long int i=1;//这里不加long会报错
vector<int> each;
if(n<10) return n*n;//进入以下的n可以保证大于10
while(n/i>0){//=0的时候,说明i的位数已经超过n了
each.push_back(s%10);
s-=(s%10);
s=s/10;
i=i*10;
}
int size=each.size();
int sum=0;
for(int i=0;i<size;++i){
sum+=each[i]*each[i];
}
return sum;
}
};
报错如下:
int的长度溢出了,改成long int就可以直接AC了
1 两数之和
有人相爱,有人夜里看海,有人力扣第一题都做不出来
写个一开始的错误版本(这个错误版本也是稍微想了一下才写出来,不是一下子就写出来了,还是忘了上次是怎么写的了)
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> myMap;
//sort(nums.begin(),nums.end());
int n=nums.size();
for(int i=0;i<n;++i){
myMap.insert({nums[i],i});
}
vector<int> result;
for(int i=0;i<n;++i){
if(myMap.count(target-nums[i])!=0 ){
result.push_back(i);
auto it= myMap.find(target-nums[i]);
result.push_back(it->second);
break;
}
}
return result;
}
};
报错用例:
想了一下发现确实,第一次把数组里所有数一股脑存到哈希表里,然后再次遍历并且对照着找哈希表里有无满足target减当前数的元素,这种情况有可能直接找到自己,然后就返回两个相同位置的元素了。
两次遍历,时间消耗也大,还可能返回相同值,怎么解决呢。
看题解去了,发现可以在第一次遍历的时候,就把数一边存入哈希表一边查询是否有满足条件的整数对,在存入表之前先查询表中有无满足条件的元素,这样很好地避免了找到自身。遂改。
上代码:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> myMap;
vector<int> result;
int n=nums.size();
for(int i=0;i<n;++i){
if(myMap.count(target-nums[i])!=0){
result.push_back(i);
auto it=myMap.find(target-nums[i]);
result.push_back(it->second);
break;
}
else{
myMap.insert({nums[i],i});
}
}
return result;
}
};
时间复杂度O(N),空间复杂度O(N)