您的位置:首页 > 其它

LeetCode: 76. Minimum Window Substring

2018-02-28 17:07 232 查看

LeetCode: 76. Minimum Window Substring

题目描述

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
串中找到一段子串
s
(窗口), 使其含有
T
串的所有字母。要求算法复杂度为
O(n)


解题思路 —— 步步为营,庖丁解牛

找到第一个窗口。

根据第一个窗口,求出下一个窗口。

以此类推,计算出最小窗口。

AC 代码

class Solution {
private:
// find the first window, [first, second).
// the second of return value is 0, if there is no window in s.
pair<size_t, size_t> findFirstWnd(string s, string t, map<char, int>& tCharNumMap)
{
if(t.empty() && !s.empty()) return {0, 1};

pair<size_t, size_t> firstWnd{0, 0};
size_t count = t.size();

for(size_t i = 0; i < s.size() && count > 0; ++i)
{
if(tCharNumMap.find(s[i]) == tCharNumMap.end())
{
continue;
}

if(count == s.size()) firstWnd.first = i;
if(tCharNumMap[s[i]] > 0)
{
--count;
}
--tCharNumMap[s[i]];

// there are enough times of the first char aka s[i] in firstWnd.
while(tCharNumMap.find(s[firstWnd.first]) == tCharNumMap.end() || tCharNumMap[s[firstWnd.first]] < 0)
{
if(tCharNumMap.find(s[firstWnd.first]) != tCharNumMap.end()) ++tCharNumMap[s[firstWnd.first]];
++firstWnd.first;
}

if(count == 0)
{
firstWnd.second = i+1;
break;
}
}
return firstWnd;
}

// find the next window.
// the second of return value is 0, if there is no more window in s.
pair<size_t, size_t> findNextWnd(string s, string t, pair<size_t, size_t> lastWnd, map<char, int>& tCharNumMap)
{
pair<size_t, size_t> nextWnd{lastWnd.first+1, 0};
++tCharNumMap[s[lastWnd.first]];

// there is enough times of the first char aka s[i] in firstWnd.
while(tCharNumMap.find(s[nextWnd.first]) == tCharNumMap.end() || tCharNumMap[s[nextWnd.first]] < 0)
{
if(tCharNumMap.find(s[nextWnd.first]) != tCharNumMap.end()) ++tCharNumMap[s[nextWnd.first]];
++nextWnd.first;
}

for(size_t i = lastWnd.second; i < s.size(); ++i)
{
if(s[i] == s[lastWnd.first])
{
nextWnd.second = i+1;
--tCharNumMap[s[i]];
break;
}

if(tCharNumMap.find(s[i]) == tCharNumMap.end()) continue;
--tCharNumMap[s[i]];

// there are enough times of the first char aka s[i] in firstWnd.
while(tCharNumMap.find(s[nextWnd.first]) == tCharNumMap.end() || tCharNumMap[s[nextWnd.first]] < 0)
{
if(tCharNumMap.find(s[nextWnd.first]) != tCharNumMap.end()) ++tCharNumMap[s[nextWnd.first]];
++nextWnd.first;
}

}

return nextWnd;
}
public:
string minWindow(string s, string t) {
// 0. calculate the apearing time of char in string t
map<char, int> tCharNumMap;
for(char ch : t)
{
++tCharNumMap[ch];
}

// 1. find the first window
pair<size_t, size_t> firstWnd = findFirstWnd(s, t, tCharNumMap);
if(firstWnd.second == 0) return "";

// 2. keep iterating the chars in string s, and find the minmum windows.
pair<size_t, size_t> lastWnd = firstWnd;
pair<size_t, size_t> minWnd = firstWnd;

while(lastWnd.second != 0)
{
pair<size_t, size_t> nextWnd = findNextWnd(s, t, lastWnd, tCharNumMap);

if(nextWnd.second != 0 && (int)nextWnd.second - (int)nextWnd.first < (int)minWnd.second - (int)minWnd.first)
{
minWnd = nextWnd;
}
lastWnd = nextWnd;
}
return s.substr(minWnd.first, minWnd.second-minWnd.first);
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: