欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[leetcode] 76. Minimum Window Substring

程序员文章站 2024-03-01 10:20:10
...

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)

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);
  }
};
相关标签: cpp