Bootstrap

[leetcode] 76. Minimum Window Substring

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
Example:

Input: S = "ADOBECODEBANC", T = "ABC"
Output: "BANC"

Note:

  • If there is no such window in S that covers all characters in T, return the empty string “”.
  • If there is such window, you are guaranteed that there will always be only one unique minimum window in S.

Solution

这个题目使用滑动窗口来解。复杂度是 O ( n ) O(n) O(n)

class Solution {
 public:
  string minWindow(string s, string t) {
  	//记录t中字符出现的次数。
    int ch[256] = {0}; 
    //记录运行过程中从pstart到pend之间字符出现的次数。
    int ch_count[256] = {0};
    //记录每个在t中出现的字符在s中的位置,因为使用滑动窗口,所以每次选择的是最先被记录的那个,采用队列。
    queue<int> positions; 
    int t_length = t.size();
    for (int i = 0; i < t_length; ++i) {
      ++ch[t[i]];
    }
    int s_length = s.size();
    /***
     * pstart 滑动窗口的起始位置
     * pend滑动窗口的结束位置
     * count用来衡量在pstart和pend之间是否包含了t中的全部字符包括字符的出现次数是否大于等于t中次数。
     * prev记录pend上次的位置,避免重复。
     */
    int pstart = -1, pend = 0, count = 0, pstart_backup = 0, pend_backup = 0, prev = -1;
    while (pend < s_length) {
      if (ch[s[pend]]) {
      	/***
      	 * 如果在pstart和pend之间出现的该字符出现的次数小于t中该字符出现的次数
      	 * 则count++,因为在后面会给该字符出现次数也加1。
      	 */
        if (ch_count[s[pend]] < ch[s[pend]]) {
          count = count + 1;
        }
        //定位第一次出现的位置。
        if (pstart == -1) {
          pstart = pend;
        }
       	//避免重复计数
        if (pend != prev) {
          positions.push(pend);
          ++ch_count[s[pend]];
          prev = pend;
        }
        //从pstart到pend时一个符合条件的子串
        if (count == t_length) {
        	//计算长度,如果需要就备份
          if(pend - pstart + 1 < pend_backup - pstart_backup || pend_backup - pstart_backup == 0) {
            pstart_backup = pstart;
            pend_backup = pend + 1;
          }
          /***
           * 移动pstart之前,移除对s[pstart]的计数
           * 此时如果s[pstart]的计数小于ch[s[pstart]],则count-1,pend后移
           */
          if ((--ch_count[s[pstart]]) < ch[s[pstart]]) {
            count = count - 1;
            pend = pend + 1;
          }
          positions.pop();
          pstart = positions.front();
        } else {
          pend = pend + 1;
        }
      } else {
        pend = pend + 1;
      }
    }
    return s.substr(pstart_backup, pend_backup - pstart_backup);
  }
};
;