forked from haoel/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
minimumWindowSubstring.cpp
122 lines (106 loc) · 3.42 KB
/
minimumWindowSubstring.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Source : https://oj.leetcode.com/problems/minimum-window-substring/
// Author : Hao Chen
// Date : 2014-07-22
/**********************************************************************************
*
* 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 emtpy string "".
*
* > If there are multiple such windows, you are guaranteed that there
* will always be only one unique minimum window in S.
*
*
**********************************************************************************/
#include <string.h>
#include <iostream>
#include <string>
using namespace std;
#define INT_MAX 2147483647
string minWindow(string s, string t) {
string win;
if (s.size()<=0 || t.size()<=0 || t.size() > s.size()) return win;
/*
* Declare two "hash map" for ASCII chars
* window[]: represents the char found in string S
* dict[]: stores the chars in string T
*/
const int MAX_CHARS = 256;
int window[MAX_CHARS], dict[MAX_CHARS];
const int NOT_EXISTED = -1;
const int NOT_FOUND = 0;
memset(dict, NOT_EXISTED, sizeof(dict));
memset(window, NOT_EXISTED, sizeof(window));
/*
* Go through the T, and inital the dict[] and window[]
* Notes: a same char can be appeared multiple times.
*/
for(int i=0; i<t.size(); i++) {
dict[t[i]]==NOT_EXISTED ? dict[t[i]]=1 : dict[t[i]]++ ;
window[t[i]] = NOT_FOUND;
}
int start =-1;
int winSize = INT_MAX;
int letterFound = 0;
int left = 0;
for(int right=0; right<s.size(); right++) {
if ( dict[s[right]] == NOT_EXISTED ){
continue;
}
/* if s[i] is existed in `t` */
char chr = s[right];
window[chr]++;
/* if one char has been found enough times, then do not do letterFound++ */
if (window[chr] <= dict[chr]) {
letterFound++;
}
if ( letterFound >= t.size() ) {
/*
* Find the left of the window - try to make the window smaller
* 1) windows[S[left]] == NOT_EXISTED ===> the char at the `left` is not in T
* 2) window[S[left]] > dict[S[left]] ===> a same char appeared more than excepted.
*/
char chl = s[left];
while ( window[chl] == NOT_EXISTED || window[chl] > dict[chl] ) {
if (dict[chl] != NOT_EXISTED ) {
//move the left of window
window[chl]--;
// reduce the number of letters found
if (window[chl] < dict[chl] ) letterFound--;
}
chl = s[++left];
}
/* Calculate the minimized window size */
if(winSize > right - left + 1){
start = left;
winSize = right - left + 1;
}
}
}
if (start>=0 && winSize>0) {
win = s.substr(start, winSize);
}
return win;
}
int main(int argc, char**argv)
{
string S = "ADOBECODEBANC";
string T = "ABC";
if (argc>2){
S = argv[1];
T = argv[2];
}
cout << "S = \"" << S << "\" T=\"" << T << "\"" <<endl;
cout << minWindow(S, T) << endl;
return 0;
}