LeetCode 76. Minimum Window Substring(最小窗口子串)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/princexiexiaofeng/article/details/79645610

题目描述:

    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", Minimum window is "BANC".
    Note:
        If there is no such window in S that covers all characters in T, return the empty string "".
        If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

分析:
    题意:给定一个字符串S,一个匹配串T,在S中找到最小连续子串,使得它包含T中所有元素,如果找不到,则返回空串。假设S长度为n,时间复杂度要求为O(n)。
    思路:这道题考察map应用双指针法的组合。假设字符串S长度为n1,T长度为n2,初始化指针left = 0,right = 0,start = -1(标记答案起始位置),cnt = n2(保存还需查找的字符串T中的元素个数),用map统计字符串T中的字符。① 如果map包含s[right]且map[s[right]]减一之后大于0,说明元素s[right]已经匹配了一个,此时cnt减一。② 当cnt = 0时,说明已经找到一个符合要求的连续子串,如果它的长度比目前的答案小,那么更新答案的起始位置start和对应的长度ans = right - left + 1;如果map包含[s[left]]且map[s[left]]加一大于等于1,说明在下一组匹配中,需要多处理一个字符s[left],此时cnt加一、指针left加一。③ 在right小于n1的范围内遍历完一遍,返回答案。
    时间复杂度为O(n1 + n2)。 

代码:

#include <bits/stdc++.h>

using namespace std;

// slicing window
class Solution {
public:
    string minWindow(string s, string t) {
		int n1 = s.length(), n2 = t.length();
		// Exceptional Case: 
		if(n1 == 0 || n2 == 0 || n1 < n2){
			return "";
		}
		map<char, int> m; 
		// count t
		for(int i = 0; i <= n2 - 1; i++){
			m[t[i]]++;
		}
		// update the window: [left, right]
        int left = 0, right = 0, ans = INT_MAX, start = -1, cnt = n2;		
		while(right <= n1 - 1){
			if(m.count(s[right])){
				if(--m[s[right]] >= 0){
					cnt--;
				}
				while(cnt == 0){
					if(right - left + 1 < ans){
						ans = right - left + 1;
						start = left;
					}
					if(m.count(s[left])){
						if(++m[s[left]] >= 1){
							cnt++;
						}
					}
					left++;
				}
			}
			right++;
		}
		if(start == -1){
			return "";
		}
		return s.substr(start, ans);
    }
};

猜你喜欢

转载自blog.csdn.net/princexiexiaofeng/article/details/79645610