242. 有效的字母异位词
题目链接:力扣
看到题目的第一想法:
看了carl哥的哈希表讲解,做这道题还算很简单的,注意其中的ASCII码转换对应其下标就可以很好地解决这道题目了,这题也是使用数组作为哈希表的经典题目了
class Solution { public: bool isAnagram(string s, string t) { // 基本思想:使用哈希表,先将s字符串中的各个字母减去a的ASCII码,然后加在hash对应的下标 // 然后用相同的方法减去t字符串的各个对应ASCII码即可 if(s.size() != t.size()) return false; int hash[26] = {0}; for(int i = 0; i < s.size(); i++) { hash[s[i] - 'a']++; } for(int i = 0; i < t.size(); i++) { hash[t[i] - 'a']--; } // 判断,若有非零项表示非有效的字母异位词 for(int i = 0; i < 26; i++) { if(hash[i] != 0) return false; } // 全部为零说明是有效的字母异位词,返回true return true; } };
遇到的问题:
暂时没有什么大问题,可以单独ac
349. 两个数组的交集
题目链接:力扣
看见题目的第一想法:
这道题一开始想到了暴力,但这样时间复杂度达到了n方,这肯定不合理,这使就要使用别的方法,比如哈希表就能很好的解决这个问题,但是题目给出了值小于1000,这样就可以用数组作为哈希表了,但是若没有这个条件,我们可以用另外一种数据结构:集合set来作为哈希表来解决这个问题,具体使用unordered_set这种集合,因为我们不需要数据有序,且可以去重,这算是更优解,下面给出2种解答方法
class Solution { public: vector<int> intersection(vector<int>& nums1, vector<int>& nums2) { // 数组实现 int nums[1001] = {0}; // 用来存放结果,set为了去重 unordered_set<int> result; for(int i = 0; i < nums1.size(); i++) { nums[nums1[i]]++; } for(int i = 0; i < nums2.size(); i++) { if(nums[nums2[i]] != 0) result.insert(nums2[i]); } return vector<int>(result.begin(),result.end()); } };
class Solution { public: vector<int> intersection(vector<int>& nums1, vector<int>& nums2) { // unordered_set实现 // 基本思路:使用set实现哈希表,先把nums1存入unorder_set里面,做到存放查找数据高效且去重 // 然后逐一将num_set和nums2做比对,相等放入result中(result也为unordered_map,主要是去重),result即为两个数组的交集 // 存放结果,达到去重效果 unordered_set<int> result; // 存放nums1存入set中的值 unordered_set<int> num_set(nums1.begin(), nums1.end()); // 将num1存入num_set for(int num : nums1) { num_set.insert(num); } // 比对num_set和nums2中是否相等,相等存入result for(int num : nums2) { if(num_set.count(num)) { result.insert(num); } } return vector<int>(result.begin(), result.end()); } };
遇到的问题:
主要是对于set这种数据结构的操作不太熟悉,去学习了一下有关set的使用方法,思维来说没太大的问题
202. 快乐数
题目链接:力扣
遇到的问题:
这题和上面那道很像,至少表达方式有所改变,所用到的知识都差不多,有了上面那题的经验这题就比较好的能够解决
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) { // 基本思路:由于若不是快乐数的话会无限循环且不会为1,说明到某个数一定会重复,且不为1 // 这样就可以用哈希表来存放这些数据,若重复出现返回false,若找到1就返回true // 定义一个存放数字平方和的set,可以统计是否出现 unordered_set<int> un_set; while(true) { int sum = getSum(n); if(sum == 1) return true; // 重复返回false if(un_set.count(sum)) break;; un_set.insert(sum); n = sum; } return false; } };
遇到的问题:
没太大的问题
1. 两数之和
题目链接:力扣
看到题目的第一想法:
这题一看就比较难以解决,算是小白噩梦了,做到哈希表这一章就自动的想到了使用哈希表实现,由于之前学过哈希表,看到这题已经大概有了思路,接下来就是用什么哈希表来实现,一开始发现结果需要存放数组数据还有其下标,前面两种方法虽然可以实现,但需要将每个元素存放为一个小的数组,比较麻烦,这时候就可以使用哈希表的第三种结构:map,但对这种结构不太熟悉,又去学习了一些关于map的使用方法才来解决这个题,但在实现的时候还是有小问题
class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { // 基本思路:定义一个map类型的哈希表,用来装nums与target的差值,然后往后遍历,若发现新遍历的值 // 在哈希表里面,说明两数相加为target,返回值即可 unordered_map<int, int> un_map; vector<int> res; for(int i = 0; i < nums.size(); i++) { auto iter = un_map.find(nums[i]); if(iter != un_map.end()) { return {iter->second, i}; } un_map.insert(pair(target-nums[i], i)); } return {}; } };
遇到的困难:
主要的困难是在实现上,一开始写的很乱,虽然思路是正确的但由于对map不熟悉或者说是对map的各项关于算法的操作不熟悉,一开始没能很好的写出来,后来看了carl的题解写的非常简洁,然后算是借鉴了这种方法来实现的我自己的思路,总体来说还不错