代码随想录-day7 哈希表(1)
1、LeetCode 242 有效的字母异位词
题目分析:
本题需要统计一个字符串中各个字符出现的次数,这是哈希表中非常经典的一种体型,使用的方法也差不多,需要掌握。前面提到,哈希表的本质就是一个数组,所以我们是可以用数组来实现哈希表的。
本题还有另一个思路:直接对两个字符串进行排序,然后直接遍历,如果出现了不一样的就不是异位词,否则就是。
题目解答:
class Solution {
public:
bool isAnagram(string s, string t) {
if (s.length() != t.length()) {
return false; // 长度都不一样,肯定不是异位词
}
vector<int> charCount(26, 0); //一共只有26个字母,所以这里设置为26
for (auto& ch : s) {
charCount[ch - 'a']++; // 不用记ascii码,直接做差即可
// 这句话是统计次数
}
for (auto& ch : t) {
// 遍历字符串t,并逐个减少字符出现的次数
// 如果二者的字符组成是一样的,那么最终都会抵消位0
charCount[ch - 'a']--;
}
// 遍历charCount数组,一旦出现了小于零的,返回false
for (auto& count : charCount) {
if (count < 0) {
return false;
}
}
return true;
}
};
本题的暴力思路再简单介绍一下暴力法。
class Solution {
public:
bool isAnagram(string s, string t) {
// 暴力法
if (s.length() != t.length()) {
return false;
}
sort(s.begin(), s.end());
sort(t.begin(), t.end());
for (int i = 0; i < s.length(); i++) {
if (s[i] != t[i]) {
return false;
}
}
return true;
}
};
上面代码的for(auto& : s)是c++11的新特性,foreach循环遍历,其中auto也是c++11新特性,自动推导类型,使用&是引用传递,防止传递参数过程中进行拷贝。
这个遍历语句,速度更快,更好用。
2、LeetCode 383 赎金信
题目分析:
这个题本质上和上面的完全一致
题目解答:
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
if (ransomNote.length() > magazine.length()) {
return false;
}
vector<int> charCount(26, 0);
for (auto& ch : magazine) {
charCount[ch - 'a']++;
}
for (auto& ch : ransomNote) {
charCount[ch - 'a']--;
if(charCount[ch - 'a'] < 0) {
return false;
}
}
return true;
}
};
3、LeetCode 49 字母异位词分组
题目分析:
本题也是一个异位词的一个题,可以借鉴之前的思路。
我们可以将strs中的每个元素排序,然后作为键,将没排序的作为值,注意,这个值是vector,因为可能有很多个,而我们最终需要的,也是这一个一个的vector。
本题中还有一个细节,使用for(auto& pair1 : umap)中,pair1是一个对组,在哈希表这里而言,pair1.first就是键,pair1.second就是值。
题目解答:
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
// string是可以作为哈希表的键的,而且经常用来当键
unordered_map<string, vector<string>> umap;
vector<vector<string>> ans;
for(string& str : strs) {
string temp = str; // 先存下来
sort(str.begin(), str.end()); // 排序作为键值
umap[str].push_back(temp); // 存在一样的键,放在vector中即可
}
// 遍历哈希表
for (auto& hashPair : umap) {
ans.push_back(hashPair.second); // 取出值,这个值就是一个vector
}
return ans;
}
};
总结:今天刚开始接触哈希表,了解了一下哈希表的基本概念。
哈希表的使用场景都是:当需要快速判断一个元素是不是在集合中,最快的方法就是使用哈希表。
前两个题不用说,最后一个题其实可以理解成:判断在,加进去(可能这里总结的不太好)。
自古奇人伟士,不屈折于忧患,则不足以其学。——方孝孺