1.代码随想录-哈希表
2.详解什么是哈希表
3.一文彻底搞定哈希表!
解题思路:
如果t是s的字母异位词,那么两个字符串中出现的字符种类和个数一定相等。
可以定义一个大小为26的数组table来记录字符串s中字符出现的次数(26个字母且都是小写),把字符映射到数组也就是哈希表的索引下标上
先遍历记录字符串s中出现的字符和种类,在遍历的时候只需要将s[i] - ‘a’ 所在的元素做+1 *** 作即可
然后遍历字符串t,减去table中对应的频次,如果出现table[i]<0,则说明t包含一个s中不存咋的字符。
class Solution {
public:
bool isAnagram(string s, string t) {
vector<int> table(26, 0);
for (int i = 0; i < s.size(); i++) { //遍历字符串A
table[s[i] - 'a']++; //s[i]字符转化为字母
}
for (int i = 0; i < t.size(); i++) { //遍历字符串B
table[t[i] - 'a']--;
}
for (int i = 0; i < 26; i++) { //record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符
if (table[i] != 0) {
return false;
}
}
return true;
}
};
官方解法中给出了另一种写法
class Solution {
public:
bool isAnagram(string s, string t) {
if (s.length() != t.length()) {
return false;
}
vector<int> table(26, 0);
for (auto& ch: s) { //遍历字符串s
table[ch - 'a']++;
}
for (auto& ch: t) {
table[ch - 'a']--;
if (table[ch - 'a'] < 0) {
return false;
}
}
return true;
}
};
题目2:349.两个数组的交集
解法:哈希集合
C++ STL unordered_set容器完全攻略
如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result_set; //存放结果
unordered_set<int> nums_set(nums1.begin(), nums1.end()); //利用拷贝构造将数组1的元素拷贝到nums_set中
for (int num : nums2) { //遍历数组2,相当于for(int num;num< nums2.size();num++)
// 发现nums2的元素 在nums_set里又出现过
if (nums_set.find(num) != nums_set.end()) { //unordered_set的find(key)成员方法
result_set.insert(num);
}
}
return vector<int>(result_set.begin(), result_set.end());
}
};
题目3:202.快乐数
解法一:哈希表
根据代码随想录的说法,当遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了。
解题思路:
输入一个数字,经过不断计算平方和后会有二种情况:1.结果为1,即快乐数;2.进入无限循环。(值不会越来越大,可以自己举几个例子)
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;
}
if (set.find(sum) != set.end()) { //如果这个sum曾经出现过,说明已经陷入了无限循环了,立刻return false
return false;
}
else {
set.insert(sum); //如果不再哈希集合中则添加这个数
}
n = sum;
}
}
};
解法二:双指针法
起始就是快慢指针的思想,和题目3:142.环形链表Ⅱ中的快慢指针异曲同工,
解题思路:
定义两个指针fast和slow,fast指针每次移动两个节点,slow指针每次移动一个节点
如果n是一个快乐数,那么fast指针会比slow先达到1;
如果n不是快乐数,那么从某个数开始就会进入无限循环,这里可以理解成一个环形链表,那么fast和slow一定会在同一个数字上相遇。
class Solution {
public:
//取数值各个位上的单数之和
int getNext(int n) {
int sum = 0;
while (n) {
sum += (n % 10) * (n % 10); //%取模(取余数)
n /= 10;
}
return sum;
}
bool isHappy(int n) {
int slow = n;
int fast = getNext(n);
while (fast != 1 && slow != fast) {
slow = getNext(slow);
fast = getNext(getNext(fast));
}
if (fast == 1) {
return true;
}
else{ //slow == fast
return false;
}
}
};
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)