1. 程式人生 > 其它 >劍指 Offer II 017. 含有所有字元的最短字串

劍指 Offer II 017. 含有所有字元的最短字串

給定兩個字串 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; } };