目录
1 3. 无重复字符的最长子串
2 438. 找到字符串中所有字母异位词
菜鸟做题第二周,语言是 C++
1 3. 无重复字符的最长子串
解题思路:
- 设置两个指针,左指针和右指针,二者之间形成窗口
- 右指针不断右移,新字母被纳入其中,窗口也变得越来越长
- 只有当窗口外的新字母与窗口内的字母重复时,左指针才右移
- 注意:在左指针右移前,还要利用它把重复的老字母去掉
用什么数据结构表示窗口?哈希表 unordered_set,帮助快速查重。
思路说明图:
假设在开始时 set/window 中只有一个字母 a 。第 1 时刻,right 指向的新字母 b 与窗口内的字母没有重复,因此将 b 纳入窗口中,right 右移一格。第 2 时刻,right 指向的新字母 c 与窗口内的字母没有重复,因此将 c 纳入窗口中,right 右移一格。第 3 时刻,right 指向的新字母 a 与窗口内的字母重复,这时 left 右移一格,起到去重的作用。以此类推。
那如何快速检验是否重复呢?借助哈希表的 find 或者 count 函数。
class Solution {
public:int lengthOfLongestSubstring(string s) {int n = s.size();if (n == 0) return 0;unordered_set<char> set;set.insert(s[0]);int right = 1, len = 0;for(int left = 0; left < n; ++left) {while (right < n && set.find(s[right]) == set.end()) {set.insert(s[right]);++right;}len = max(len, right - left);set.erase(s[left]);}return len;}
};
2 438. 找到字符串中所有字母异位词
我鼠啦,一直想着用哈希表减少时间,结果答案根本没用哈希表。。。因为该题中的字母是允许重复的,所以哈希表的查重功能貌似派不上用场。
解题思路:
- 窗口长度是固定的,且为 p 字符串的长度
- 让窗口在 s 字符串上不断右移
- 通过窗口内各字母的个数来判断是不是异位词
本题和上一题的窗口有两个不同点。一是,本题的窗口长度是固定的,而上一题的窗口是逐渐变长的;二是,本题的窗口被实例为 vector<int> 用于装 26 个字母的个数,而上一题的窗口直接用于装字母。
class Solution {
public:vector<int> findAnagrams(string s, string p) {int sLen = s.size(), pLen = p.size();vector<int> sCount(26), pCount(26);vector<int> ans;if (sLen < pLen) return {};// 初始化窗口for (int i = 0; i < pLen; ++i) {++sCount[s[i] - 'a'];++pCount[p[i] - 'a'];}if (sCount == pCount) ans.push_back(0);// 不断右移窗口for (int i = 0; i < sLen - pLen; ++i) {--sCount[s[i] - 'a'];++sCount[s[i + pLen] - 'a'];if (sCount == pCount) ans.push_back(i + 1);}return ans;}
};