注:key值和value是不同的,key指下标索引,value是该索引存在的值
两个表格应该熟知,对不同的情况用不同的容器可以使时间和空间复杂度得到最优
优解:思路:首先构建一个哈希表,即长度26的数组record,该数组的作用记录字母出现次数,下标0为a,1为b,以此类推下标25为z.然后先遍历串s,把出现过的字母对应下标+1(记录串s字母出现的次数);再遍历串t,相应出现的字母减1.最后把record数组从头遍历一遍,若全为0,则证明串s和串t的字母出现的次数都刚刚好,若有任何一个不为0,则说明串s或串t有多的或少的字母。
通过s[i]-'a'用下标进行映射,两者相减刚好是对应record数组下标对应字母。
代码:
bool isAnagram(string s, string t) {
int record[26] = {0};
for(int i = 0;i < s.size();i++){//统计串s字母出现次数
record[s[i] - 'a']++;
}
for(int i = 0;i < t.size();i++){//串t出现的字母相应的减去
record[t[i] - 'a']--;
}
for(int i = 0;i < 26;i++){//判断两串出现字母的次数是否相等
if(record[i] != 0)
return false;
}
return true;
}
本题可用数组或集合实现,若元素少且最大的元素值大则考虑用集合。集合的优点是自动去除重复元素,方法多,且时间复杂度低。
思路:用低层容器为哈希表的set实现,先把nums1转换为集合,再遍历nums2和nums1的集合想比较,相同的元素存储到结果集合中,最后再把结果集合转换为数组返回。
tip:set.find()的定义
从set容器中查找值为x的元素
若存在,返回一个迭代器指向x,若不存在,返回一个迭代器指向set.end()
代码:
vector intersection(vector& nums1, vector& nums2) {
unordered_set result_set;//存放两集合相同的元素
unordered_set nums_set(nums1.begin(),nums1.end());//把nums1转换为set
for(int nums:nums2){
if(nums_set.find(nums) != nums_set.end()){
result_set.insert(nums);
}//若相等则存储该元素
}
return vector(result_set.begin(),result_set.end());
}
题意:例如1,拆开为1和9,分别平方相加等于82,再把82拆开成8和2,平方相加,以此类推。和为1既快乐数。
思路:例如19两位数,两位数每个位置最大都为9,则2位数的平方求和为,若在平方求和途中出现重复的数,则证明此时已经出现了环,若没出现和为1,则以后肯定也不会再出现,因为此时已经在环内无限循环。
可以用142题的双指针法来判断环的出现,也可用集合的方法。
代码:以下为集合的方法,可以快速判断是否有出现重复的元素
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){//和为1为快乐数
return true;
}
if(set.find(sum) != set.end()){//该和在集合中出现过,则出现了环
return false;
}
else{
set.insert(sum);
}
n = sum;
}
}
思路:若目标值20,当前数组值为2的时候,可以往前查找是否有值为18的元素,若有返回两数的下标,没有则继续往后遍历到数组结束。
解1(暴力解):利用两个for循环,外层循环从数组头遍历到数组尾,外层遍历到一个值时,内层for就往前找是否有相符的差值,若有返回两者下标,没有则继续遍历结束。
解2(map):因为需要查找值且要知道该值的数组下标,并且还需查集合是否有出现过的元素,此时可以用map。从头遍历数组,每次都在map中查询该下标值与目标值的差值在集合中是否出现过,若出现过则返回当前遍历的下标和在集合中查找的下标,若没有则继续把该遍历值和下标存储在map中,循环到结束。
vector twoSum(vector& nums, int target) {
std::unordered_map map;
for(int i = 0;i < nums.size();i++){
auto iter = map.find(target - nums[i]);//把数组与目标值相差的值存储到迭代器
if(iter != map.end()){//该差值元素存在于集合中,返回两个元素的下标
return {iter->second,i};
}
map.insert(pair (nums[i],i));//没找到之前有符合的值,则把当前的键值对存储到map中
}
return {};//没有符合的数,返回空
}