From 2d823049c360a7018cc2db9015df4cdf6b0b4e0d Mon Sep 17 00:00:00 2001 From: ShusenTang Date: Fri, 28 Feb 2020 23:46:12 +0800 Subject: [PATCH] add 76. Minimum Window Substring :beer: --- README.md | 1 + solutions/76. Minimum Window Substring.md | 44 +++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 solutions/76. Minimum Window Substring.md diff --git a/README.md b/README.md index d6f1628..9154709 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ My LeetCode solutions with Chinese explanation. 我的LeetCode中文题解。 | 73 |[Set Matrix Zeroes](https://leetcode.com/problems/set-matrix-zeroes/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/73.%20Set%20Matrix%20Zeroes.md)|Medium| | | 74 |[Search a 2D Matrix](https://leetcode.com/problems/search-a-2d-matrix/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/74.%20Search%20a%202D%20Matrix.md)|Medium| | | 75 |[Sort Colors](https://leetcode.com/problems/sort-colors/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/75.%20Sort%20Colors.md)|Medium| | +| 76 |[Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/)|[C++](solutions/76.%20Minimum%20Window%20Substring.md)|Hard| | | 77 |[Combinations](https://leetcode.com/problems/combinations/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/77.%20Combinations.md)|Medium| | | 78 |[Subsets](https://leetcode.com/problems/subsets/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/78.%20Subsets.md)|Medium| | | 79 |[Word Search](https://leetcode.com/problems/word-search/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/79.%20Word%20Search.md)|Medium| | diff --git a/solutions/76. Minimum Window Substring.md b/solutions/76. Minimum Window Substring.md new file mode 100644 index 0000000..9a122d6 --- /dev/null +++ b/solutions/76. Minimum Window Substring.md @@ -0,0 +1,44 @@ +# [76. Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/) + +# 思路 + +给定字符串S和T,要在S中找到一个最短的子串,使得其包含了T中的所有的字母,并且限制时间复杂度为 O(n)。 + +由于限制时间复杂度为O(n),所以我最开始想到的思路是双指针法,用两个指针 l 和 r 从S的两端分别向中间缩小,但是发现这样得出的子串不一定就是最小的。 + +看了答案发现也是用双指针,不过不是从两端往中间缩小,而是都从最左边开始,先将 r 不断右移以扩大窗口直到包含了T的所有字符,然后在包含T中所有字符的前提下尝试将 l 不断右移缩小窗口。这样一伸一缩后就是求得了当前最小的一个子串,然后再用同样的思路将两个指针向右滑动,用一个全局变量记录整个过程的最短长度。 + +我们可以用一个长度为128(ASCII码为0-127)的整型数组 cnt 来记录T串每个字符的出现次数,然后还需要用一个变量 win_cnt 来记录在窗口中的包含在T中的字符数,这样如果 `win_cnt == T.size()`就说明找到了满足条件的子串,更新全局变量的最短长度和起始位置。 + +需要特别注意 win_cnt 的更新方式,当某个字符c进入窗口时,只有当`--cnt[c] >= 0`时才使 cnt 加1;同理,当某个字符 c 离开窗口时,只有当`++cnt[c] > 0`时才使 cnt 减 1。 + +时间复杂度O(m+n) + +# C++ +``` C++ +class Solution { +public: + string minWindow(string s, string t) { + int sn = s.size(), tn = t.size(); + vectorcnt(128, 0); + for(int i = 0; i < tn; i++) cnt[t[i]]++; + + int win_cnt = 0; + int l = 0, smallest_l = -1, smallest = INT_MAX; + for(int r = 0; r < sn; r++){ + if(--cnt[s[r]] >= 0) win_cnt++; + + while(win_cnt == tn){ + if(smallest > r - l + 1){ + smallest = r - l + 1; + smallest_l = l; + } + if(++cnt[s[l]] > 0) win_cnt--; + l++; + } + } + + return smallest_l == -1 ? "" : s.substr(smallest_l, smallest); + } +}; +``` \ No newline at end of file