Hust oj 1758 Minimum Window Substring(最小覆盖子串问题)

Minimum Window Substring
Time Limit: 1000 MSMemory Limit: 65535 K
Total Submit: 42(15 users)Total Accepted: 27(13 users)Rating: Special Judge: No
Description

Given a string S and a string T, find the minimum window in S which will contain all the characters.

For example,

S = "ADOBECODEBANC"

T = "ABC"

Minimum window is "BANC".

Note:

If there are multiple such windows, you are guaranteed the window with the shortest length and first appeared in the string S.

Input

There are multiple test cases, processing to the end-of-file.

For each case:

Line 1: This line contains string S.

Line 2: This line contains string T.

The string contains printable characters except space (visible characters).

The length of the string is not less than 1 and not greater than 100,000.

Output

For each case:

Output one line, contains the minimum window substring.

If there is no such window in S that covers all characters in T, output the empty string "".

Sample Input
ADOBECODEBANC
ABC
acbdbaab
aabd
adobecodebancbbcaa
abc
203838534736761996179497200837
746
ZHEXOMNHPRWMAJFPSUCYFZXUNLNRRU
YUX
dptpeaevzsykxnfurfbqcxdqkujgtc
urn
uLY7JdYK1810x95bT3LyPx7V37iLjY
Jx8
w_J)u^^@gsWoXnTB*@CWAh./k9d3|%
^3w
Sample Output
BANC
dbaa
bca
4736
YFZXU
nfur
JdYK1810x
w_J)u^^@gsWoXnTB*@CWAh./k9d3
LeetCode上的一道题,从别人那里学到了O(n)复杂度的算法,感觉很巧妙,维护一个合法的窗口,不断缩小这个窗口来达到求最短字符串的目的,双指针加贪心,具体的可以看这篇博客:http://www.cnblogs.com/lichen782/p/leetcode_minimum_window_substring_3.html

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int Maxn = 100005;
char str1[Maxn];
char str2[Maxn];
int FirMap[260];
int SecMap[260];
int tempStart,tempEnd;
int Start,End;
int MinLength;

int main()
{
    while(~scanf("%s",&str1))
    {
        scanf("%s",&str2);
        memset(FirMap,0,sizeof(FirMap));
        memset(SecMap,0,sizeof(SecMap));
        int len_1 = strlen(str1);
        int len_2 = strlen(str2);
        for(int i=0;i<len_2;i++)
        {
            FirMap[str2[i]]++;
        }
        int ans = 0;
        MinLength = len_1;
        End = len_1;
        Start = -1;
        tempStart = 0;
        int i;
        for(int i=0;i<len_1;i++)
        {
            SecMap[str1[i]]++;
            if(SecMap[str1[i]] <= FirMap[str1[i]])
            {
                ans++;
            }
            if(ans == len_2)
            {
                while(tempStart < i && SecMap[str1[tempStart]] > FirMap[str1[tempStart]])
                {
                    SecMap[str1[tempStart]]--;
                    tempStart++;
                }

                if(i - tempStart < MinLength)
                {
                    MinLength = i - tempStart;
                    End = i;
                    Start = tempStart;
                }
                SecMap[str1[tempStart]]--;
                ans--;
                tempStart++;
            }
        }
           if(Start != -1)
                for(int i=Start;i<=End;i++)
                {
                    printf("%c",str1[i]);
                }
        printf("\n");
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值