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

本文介绍了一种在字符串S中寻找包含另一字符串T所有字符的最小子串算法,时间复杂度为O(n),通过使用map和双指针技巧实现。

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

题目描述:

    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);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值