一、哈希法
当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法
unordered_set
二、242. 有效的字母异位词
第一遍自己写
#include<string>
class Solution {
public:
bool isAnagram(string s, string t) {
vector<int>a(26);
vector<int>b(26);
for(int i=0;i<s.size();i++){
a[s[i]-'a']++;
}
for(int i=0;i<t.size();i++){
b[t[i]-'a']++;
}
for(int i=0;i<26;i++){
if(a[i] != b[i]){
return false;
}
}
return true;;
}
};
可以优化的部分
#include<string>
class Solution {
public:
bool isAnagram(string s, string t) {
vector<int>a(26);
for(int i=0;i<s.size();i++){
a[s[i]-'a']++;
}
for(int i=0;i<t.size();i++){
a[t[i]-'a']--;
}
for(int i=0;i<26;i++){
if(0 != a[i]){
return false;
}
}
return true;;
}
};
小结
我自己写的时候用了两个数组,优化后只用一个数组,s让数组++,t让数组--,最后为0就行,节省了空间。
三、349. 两个数组的交集
自己熟悉set写出来的shit
很怪,好歹ac了不是。
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
set<int>record1;
set<int>record2;
vector<int>record(1000);
vector<int>result;
for(int i=0;i<nums1.size();i++){
record1.insert(nums1[i]);
}
for(int i=0;i<nums2.size();i++){
record2.insert(nums2[i]);
}
set<int>::iterator it;
for(it = record1.begin(); it != record1.end(); it++){
record[(*it)]++;
}
for(it = record2.begin(); it != record2.end(); it++){
record[(*it)]++;
}
for(int i=0;i<record.size();i++){
if(record[i]==2){
result.push_back(i);
}
}
return result;
}
};
代码随想录上的
主要还是熟悉熟悉set和map的API吧,不然好多不会用,要去查。
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result_set; // 存放结果,之所以用set是为了给结果集去重
unordered_set<int> nums_set(nums1.begin(), nums1.end());
for (int num : nums2) {
// 发现nums2的元素 在nums_set里又出现过
if (nums_set.find(num) != nums_set.end()) {//find如果找到,返回指向该元素的迭代器,如果没找到,返回end。
//这里的意思是出现过这个num,则inert到最终集合里
result_set.insert(num);
}
}
return vector<int>(result_set.begin(), result_set.end());
}
};
四、202. 快乐数
自己取巧做的
首先是取n的平方和,这个之前有做过,很熟,然后想到了递归,因为循环判断结束的条件我是不知道的,所以我一个一个去试了,用来作为递归的终止条件,试到7就ac了
class Solution {
public:
bool isHappy(int n) {
if(n==1){
return true;
}
if(n<7){
return false;
}
return isHappy(geta(n));
}
int geta(int n){
int sum=0,tmp;
while(0 != n){
tmp = n%10;
sum+= tmp*tmp;
n/=10;
}
return sum;
};
};
看了解析后
关键还是在于unordered的使用吧,意识到会出现循环,那么和前面的成环链表有些类似,那一题也能用这种方法,即哈希法,即当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了。这句话太关键了!!!!
class Solution {
public:
bool isHappy(int n) {
unordered_set<int>a;
while(1){
if(n==1){
return true;
}
int sum = getsum(n);
if(a.find(sum) != a.end()){
return false;
}else{
a.insert(sum);
}
n = sum;
}
}
int getsum(int n){
int sum=0,tmp;
while(0 != n){
tmp = n%10;
sum+= tmp*tmp;
n/=10;
}
return sum;
};
};
五、1. 两数之和
暴力解
直接双重循环遍历就行了。时间复杂度O(n^2)
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
//暴力解
vector<int>result;
int size = nums.size();
for(int i=0;i<size-1;i++){
for(int j=i+1;j<size;j++){
if(nums[i]+nums[j]==target){
result.push_back(i);
result.push_back(j);
}
}
}
return result;
}
};
2.
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++) {
// 遍历当前元素,并在map中寻找是否有匹配的key
auto iter = map.find(target - nums[i]);
if(iter != map.end()) {
return {iter->second, i};//return的形式不是很理解
}
// 如果没找到匹配对,就把访问过的元素和下标加入到map中
map.insert(pair<int, int>(nums[i], i));
}
return {};
}
};
六、总结
对于vector来说,如pusk_back是非常好用的函数,用法也简单。
对于set和map 的一些主要函数一定要会用,如insert find begin end ,需要注意的是返回值是迭代器的时候的用法。
(5小时)