leetcode76. 最小覆盖子串(传引用 unordered_map的慢 可以用数组来代替哈希表)
6873 分钟
原文链接:https://www.cnblogs.com/Time25/p/19674744.html
解法1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class Solution{ bool is_covered(unordered_map<int,int>&cnt_s,unordered_map<int,int>&cnt_t){ for(int i='A';i<='Z';i++){ if(cnt_s[i]<cnt_t[i])return false; } for(int i='a';i<='z';i++){ if(cnt_s[i]<cnt_t[i])return false; } return true; } public: string minWindow(string s, string t) { unordered_map<int,int>cnt_s,cnt_t; int left=0,m=s.length(),temp_left=-1,temp_right=m,ans=INT_MAX; for(char i:t)cnt_t[i]++; for(int i=0;i<m;i++){ cnt_s[s[i]]++; while(is_covered(cnt_s,cnt_t)){ if(i-left+1<temp_right-temp_left+1){ temp_left=left; temp_right=i; } cnt_s[s[left]]--; left++; } } return (temp_left<0?"":s.substr(temp_left,temp_right-temp_left+1)); } };
|
解法2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| class Solution2 { bool is_covered(int cnt_s[], int cnt_t[]) { for (int i = 'A'; i <= 'Z'; i++) { if (cnt_s[i] < cnt_t[i]) { return false; } } for (int i = 'a'; i <= 'z'; i++) { if (cnt_s[i] < cnt_t[i]) { return false; } } return true; }
public: string minWindow(string s, string t) { int cnt_s[128]{}; int cnt_t[128]{};
for (char c : t) { cnt_t[c]++; }
int m = s.size(); int ans_left = -1, ans_right = m; int left = 0; for (int right = 0; right < m; right++) { cnt_s[s[right]]++; while (is_covered(cnt_s, cnt_t)) { if (right - left < ans_right - ans_left) { ans_left = left; ans_right = right; } cnt_s[s[left]]--; left++; } } return ans_left < 0 ? "" : s.substr(ans_left, ans_right - ans_left + 1); } };
|
解法2优化
这个优化的方案是,上一个解法每次都要花费时间去看是不是is_covered,也就是O(52),我们可以直接维护一个less,表示t中没有出现过的字符的种类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class Solution3{ public: string minWindow(string s,string t){ int cnt[128]{}; int less=0,m=s.length(),temp_left=-1,temp_right=m,left=0; for(char&i:t){ if(cnt[i]==0)less++; cnt[i]++; } for(int right=0;right<m;right++){ cnt[s[right]]--; if(cnt[s[right]]==0)less--; while(less==0){ if(right-left+1<temp_right-temp_left+1){ temp_right=right; temp_left=left; } if(cnt[s[left]]==0)less++; cnt[s[left]]++; left++; } } return (temp_left<0?"":s.substr(temp_left,temp_right-temp_left+1)); } };
|
// TRAINING LOG · 第 14 / 76 篇训练记录 · 成文于 2026.03.05 · 夜间 19:21