劍指 Offer II 017. 含有所有字元的最短字串
阿新 • • 發佈:2022-04-05
給定兩個字串 s 和 t 。返回 s 中包含 t 的所有字元的最短子字串。如果 s 中不存在符合條件的子字串,則返回空字串 "" 。
如果 s 中存在多個符合條件的子字串,返回任意一個。
注意: 對於 t 中重複字元,我們尋找的子字串中該字元數量必須不少於 t 中該字元數量。
示例 1:
輸入:s = "ADOBECODEBANC", t = "ABC"
輸出:"BANC"
解釋:最短子字串 "BANC" 包含了字串 t 的所有字元 'A'、'B'、'C'
示例 2:
輸入:s = "a", t = "a"
輸出:"a"
示例 3:
輸入:s = "a", t = "aa"
輸出:""
解釋:t 中兩個字元 'a' 均應包含在 s 的子串中,因此沒有符合條件的子字串,返回空字串。
提示:
1 <= s.length, t.length <= 105
s 和 t 由英文字母組成
解析:
雙指標,
vis1統計t中每個字元的個數
vis2統計s中遍歷到i時每個字元的個數,
如果vis2中每個字元的個數大於等於vis1,則記錄當前長度和起點終點(如果當前長度小於maxLen的話)
並起點向後走,如果仍然符合上述條件,則更新最大長度,記錄起點終點,直至不符合上述條件
r向後走
class Solution { public: bool check(const vector<int>& vis1, const vector<int>& vis2) { for(int j = 0; j < 58; j++) { if(vis2[j] < vis1[j]) { return false; } } return true; } string minWindow(string s, string t) { int n = s.length(); int m = t.length(); if(m > n) return""; int cnt = 100010, x = 0, y = 0; vector<int> vis1(58, 0), vis2(58, 0); for(int i = 0; i < m; i++) { vis1[t[i] - 'A']++; } int l = 0; for(int i = 0; i < n; i++) { vis2[s[i] - 'A']++; while(check(vis1, vis2)) { if(i - l + 1 < cnt) { cnt = i - l + 1; x = l, y = i; } vis2[s[l] - 'A']--; l++; } } if(cnt == 100010) return ""; string ret = ""; for(int i = x; i <= y; i++) ret += s[i]; return ret; } };