LeetCode 76. Minimum Window Substring

本文介绍了一种在字符串S中寻找包含字符串T所有字符的最短子串的算法。通过使用滑动窗口技术和哈希映射,该算法能在O(n)的时间复杂度内找到符合条件的最小子串。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <string>
#include <unordered_map>
#include <vector>
#include <iostream>
using namespace std;

/*
  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). 
  For example:
  S = "ADOBECODEBANC"
  T = "ABC"
  minumum window is "BANC".
  If there is no such window in S that convers all characters in T, return the empty string "".
*/
string minWindow(string s, string t) {
  int minLen = s.size()+1;
  int minBegin = 0;
  int tSize = t.size();
  vector<int> count(256, 0);
  vector<int> needed(256, 0);
  for(int i = 0; i < tSize; ++i) {
      needed[t[i]]++;
  }
  int tCount = 0;
  for(int begin = 0, end = 0; end < s.size(); ++end) {
    char tmp = s[end];
    if(!needed[tmp]) continue;
    /* find the longest length that contains all the t chars.*/
    if(++count[tmp] <= needed[tmp]) {
        tCount++;
    }
    /* shrink the range to find the shortest one.*/
    if(tCount == tSize) {
      /* think about this case "AAAABC"*/
      while(needed[s[begin]] == 0 || count[s[begin]] > needed[s[begin]]) {
        if(count[s[begin]] > needed[s[begin]]) {count[s[begin]]--;};
        begin++;
      }
      int length = end - begin + 1;
      if(length < minLen) {
        minLen = length;
        minBegin = begin;
      }
    }
  }
  return minLen > s.size() ? "" : s.substr(minBegin, minLen);
}

int main(void) {
  cout << minWindow("ADOBECODEBANC", "ABC") << endl;
}
 


Facebook asked a simplified version.

#include "header.h"
using namespace std;

string minWindowSubstring(string str, unordered_set<char> chars) {
  unordered_map<char, int> charToCount;
  int windowSize = str.size() + 1, minStart = 0;
  int count = 0;
  for(int start = 0, end = 0; end < str.size(); ++end) {
    char ch = str[end];
    if(chars.find(ch) == chars.end()) continue;
    if(charToCount[ch] == 0) {count++; charToCount[ch] = 1;}
    else charToCount[ch]++;
    if(count == chars.size()) {
    cout << "count size : " << count << " "<< "charToCount.size() : " << charToCount.size() << endl; // it is very weird here.
      while((chars.find(str[start]) == chars.end()) || (charToCount[str[start]] > 1)) {
        if(charToCount[str[start]] > 1) charToCount[str[start]]--;
        start++;
      }
      int size = end - start + 1;
      if(windowSize > size) {
        windowSize = size;
        minStart = start;
      }
    }
  }
  return windowSize > str.size() ? "" : str.substr(minStart, windowSize);
}

int main(void) {
  unordered_set<char> inputs{'a', 'b', 'c'};
  cout << minWindowSubstring("adabbcbbabc", inputs) << endl;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值