1. 76. 最小覆盖子串

  1. class Solution {
  2. public:
  3. string minWindow(string s, string t) {
  4. unordered_map<char,int> need,window;
  5. for(char c:t){
  6. need[c]++;
  7. }
  8. int left=0,right=0;
  9. int valid=0;
  10. //记录最小覆盖字串的起始索引和长度
  11. int start=0,len=INT_MAX;
  12. while(right<s.size()){
  13. //c是将移入窗口的字符
  14. char c=s[right];
  15. //右移窗口
  16. right++;
  17. if(need.count(c)){
  18. window[c]++;
  19. if(window[c]==need[c]){
  20. valid++;
  21. }
  22. }
  23. //判断窗口是否收缩
  24. while(valid==need.size()){
  25. //收缩窗口时更新数据,更新最小覆盖字串
  26. if(right-left<len){
  27. start=left;
  28. len=right-left;
  29. }
  30. //d是将要移出窗口的字符
  31. char d=s[left];
  32. //窗口左移
  33. left++;
  34. //进行窗口内数据的一系列更新
  35. if(need.count(d)){
  36. if(window[d]==need[d]){
  37. valid--;
  38. }
  39. window[d]--;
  40. }
  41. }
  42. }
  43. //返回最小覆盖子串
  44. return len==INT_MAX?" ":s.substr(start,len);
  45. }
  46. };

2. 567. 字符串的排列

  1. class Solution {
  2. public:
  3. bool checkInclusion(string s1, string s2) {
  4. unordered_map<char,int> need,window;
  5. for(char c:s1){
  6. need[c]++;
  7. }
  8. int left=0,right=0;
  9. int valid=0;
  10. while(right<s2.size()){
  11. char c=s2[right];
  12. right++;
  13. // 进行窗口内数据的一系列更新
  14. if(need.count(c)){
  15. window[c]++;
  16. if(window[c]==need[c]){
  17. valid++;
  18. }
  19. }
  20. // 判断左侧窗口是否要收缩
  21. while(right-left>=s1.size()){
  22. // 在这里判断是否找到了合法的子串
  23. if(valid==need.size()){
  24. return true;
  25. }
  26. char c=s2[left];
  27. left++;
  28. // 进行窗口内数据的一系列更新
  29. if(need.count(c)){
  30. if(window[c]==need[c]){
  31. valid--;
  32. }
  33. window[c]--;
  34. }
  35. }
  36. }
  37. return false;
  38. }
  39. };

3. 438. 找到字符串中所有字母异位词

  1. class Solution {
  2. public:
  3. vector<int> findAnagrams(string s, string p) {
  4. unordered_map<char,int> need,window;
  5. for(char c:p){
  6. need[c]++;
  7. }
  8. int left=0,right=0;
  9. int valid=0;
  10. //记录结果
  11. vector<int> res;
  12. while(right<s.size()){
  13. char c=s[right];
  14. right++;//扩大窗口
  15. // 进行窗口内数据的一系列更新
  16. if(need.count(c)){
  17. window[c]++;
  18. if(window[c]==need[c]){
  19. valid++;
  20. }
  21. }
  22. // 判断左侧窗口是否要收缩
  23. while(right-left>=p.size()){
  24. // 当窗口符合条件时,把起始索引加入 res
  25. if(valid==need.size()){
  26. res.push_back(left);
  27. }
  28. char c=s[left];
  29. left++;
  30. // 进行窗口内数据的一系列更新
  31. if(need.count(c)){
  32. if(need[c]==window[c]){
  33. valid--;
  34. }
  35. window[c]--;
  36. }
  37. }
  38. }
  39. return res;
  40. }
  41. };

4. 3. 无重复字符的最长子串

  1. class Solution {
  2. public:
  3. int lengthOfLongestSubstring(string s) {
  4. unordered_map<char,int> window;
  5. int left=0,right=0;
  6. int res=0;
  7. while(right<s.size()){
  8. char c=s[right];
  9. right++;
  10. // 进行窗口内数据的一系列更新
  11. window[c]++;
  12. // 判断左侧窗口是否要收缩,是否存在重复元素
  13. while(window[c]>1){
  14. char d=s[left];
  15. left++;
  16. // 进行窗口内数据的一系列更新
  17. window[d]--;
  18. }
  19. // 在这里更新答案,在判断完是否有重复元素后再更新
  20. res=max(res,right-left);
  21. }
  22. return res;
  23. }
  24. };