Skip to content

Commit 92b8ff2

Browse files
committed
feat: add solutions to lcof2 problem: No.017
1 parent 5932d02 commit 92b8ff2

File tree

4 files changed

+460
-1
lines changed

4 files changed

+460
-1
lines changed

lcof2/剑指 Offer II 017. 含有所有字符的最短字符串/README.md

+240-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
<pre>
2020
<strong>输入:</strong>s = &quot;ADOBECODEBANC&quot;, t = &quot;ABC&quot;
21-
<strong>输出:</strong>&quot;BANC&quot;
21+
<strong>输出:</strong>&quot;BANC&quot;
2222
<strong>解释:</strong>最短子字符串 &quot;BANC&quot; 包含了字符串 t 的所有字符 &#39;A&#39;&#39;B&#39;&#39;C&#39;</pre>
2323

2424
<p><strong>示例 2:</strong></p>
@@ -57,22 +57,261 @@
5757

5858
<!-- 这里可写通用的实现逻辑 -->
5959

60+
滑动窗口,当窗口包含全部需要的的字符后,进行收缩,以求得最小长度
61+
62+
进阶解法:利用 `count` 变量避免重复对 `need``window` 进行扫描
63+
6064
<!-- tabs:start -->
6165

6266
### **Python3**
6367

6468
<!-- 这里可写当前语言的特殊实现逻辑 -->
6569

6670
```python
71+
class Solution:
72+
def minWindow(self, s: str, t: str) -> str:
73+
m, n = len(s), len(t)
74+
if n > m:
75+
return ""
76+
need, window = defaultdict(int), defaultdict(int)
77+
for c in t:
78+
need[c] += 1
79+
start, minLen = 0, float('inf')
80+
left, right = 0, 0
81+
while right < m:
82+
window[s[right]] += 1
83+
right += 1
84+
while self.check(need, window):
85+
if right - left < minLen:
86+
minLen = right - left
87+
start = left
88+
window[s[left]] -= 1
89+
left += 1
90+
return "" if minLen == float('inf') else s[start:start + minLen]
91+
92+
def check(self, need, window):
93+
for k, v in need.items():
94+
if window[k] < v:
95+
return False
96+
return True
97+
```
6798

99+
进阶解法
100+
101+
```python
102+
class Solution:
103+
def minWindow(self, s: str, t: str) -> str:
104+
m, n = len(s), len(t)
105+
if n > m:
106+
return ""
107+
need, window = defaultdict(int), defaultdict(int)
108+
needCount, windowCount = 0, 0
109+
for c in t:
110+
if need[c] == 0:
111+
needCount += 1
112+
need[c] += 1
113+
start, minLen = 0, float('inf')
114+
left, right = 0, 0
115+
while right < m:
116+
ch = s[right]
117+
right += 1
118+
if ch in need:
119+
window[ch] += 1
120+
if window[ch] == need[ch]:
121+
windowCount += 1
122+
while windowCount == needCount:
123+
if right - left < minLen:
124+
minLen = right - left
125+
start = left
126+
ch = s[left]
127+
left += 1
128+
if ch in need:
129+
if window[ch] == need[ch]:
130+
windowCount -= 1
131+
window[ch] -= 1
132+
return "" if minLen == float('inf') else s[start:start + minLen]
68133
```
69134

70135
### **Java**
71136

72137
<!-- 这里可写当前语言的特殊实现逻辑 -->
73138

74139
```java
140+
class Solution {
141+
public String minWindow(String s, String t) {
142+
int m = s.length(), n = t.length();
143+
if (n > m) {
144+
return "";
145+
}
146+
Map<Character, Integer> need = new HashMap<>();
147+
Map<Character, Integer> window = new HashMap<>();
148+
for (char ch : t.toCharArray()) {
149+
need.merge(ch, 1, Integer::sum);
150+
}
151+
int start = 0, minLen = Integer.MAX_VALUE;
152+
int left = 0, right = 0;
153+
while (right < m) {
154+
window.merge(s.charAt(right++), 1, Integer::sum);
155+
while (check(need, window)) {
156+
if (right - left < minLen) {
157+
minLen = right - left;
158+
start = left;
159+
}
160+
window.merge(s.charAt(left++), -1, Integer::sum);
161+
}
162+
}
163+
return minLen == Integer.MAX_VALUE ? "" : s.substring(start, start + minLen);
164+
}
165+
166+
private boolean check(Map<Character, Integer> need, Map<Character, Integer> window) {
167+
for (Map.Entry<Character, Integer> entry : need.entrySet()) {
168+
if (window.getOrDefault(entry.getKey(), 0) < entry.getValue()) {
169+
return false;
170+
}
171+
}
172+
return true;
173+
}
174+
}
175+
```
176+
177+
进阶解法
178+
179+
```java
180+
class Solution {
181+
public String minWindow(String s, String t) {
182+
int m = s.length(), n = t.length();
183+
if (n > m) {
184+
return "";
185+
}
186+
Map<Character, Integer> need = new HashMap<>();
187+
Map<Character, Integer> window = new HashMap<>();
188+
int needCount = 0, windowCount = 0;
189+
for (char ch : t.toCharArray()) {
190+
if (!need.containsKey(ch)) {
191+
needCount++;
192+
}
193+
need.merge(ch, 1, Integer::sum);
194+
}
195+
int start = 0, minLen = Integer.MAX_VALUE;
196+
int left = 0, right = 0;
197+
while (right < m) {
198+
char ch = s.charAt(right++);
199+
if (need.containsKey(ch)) {
200+
int val = window.getOrDefault(ch, 0) + 1;
201+
if (val == need.get(ch)) {
202+
windowCount++;
203+
}
204+
window.put(ch, val);
205+
}
206+
while (windowCount == needCount) {
207+
if (right - left < minLen) {
208+
minLen = right - left;
209+
start = left;
210+
}
211+
ch = s.charAt(left++);
212+
if (need.containsKey(ch)) {
213+
int val = window.get(ch);
214+
if (val == need.get(ch)) {
215+
windowCount--;
216+
}
217+
window.put(ch, val - 1);
218+
}
219+
}
220+
}
221+
return minLen == Integer.MAX_VALUE ? "" : s.substring(start, start + minLen);
222+
}
223+
}
224+
```
225+
226+
### **Go**
227+
228+
```go
229+
func minWindow(s string, t string) string {
230+
m, n := len(s), len(t)
231+
if n > m {
232+
return ""
233+
}
234+
need, window := make(map[byte]int), make(map[byte]int)
235+
for _, r := range t {
236+
need[byte(r)]++
237+
}
238+
start, minLen := 0, math.MaxInt32
239+
left, right := 0, 0
240+
for right < m {
241+
window[s[right]]++
242+
right++
243+
for check(need, window) {
244+
if right-left < minLen {
245+
minLen = right - left
246+
start = left
247+
}
248+
window[s[left]]--
249+
left++
250+
}
251+
}
252+
if minLen == math.MaxInt32 {
253+
return ""
254+
}
255+
return s[start : start+minLen]
256+
}
257+
258+
func check(need, window map[byte]int) bool {
259+
for k, v := range need {
260+
if window[k] < v {
261+
return false
262+
}
263+
}
264+
return true
265+
}
266+
```
75267

268+
进阶解法
269+
270+
```go
271+
func minWindow(s string, t string) string {
272+
m, n := len(s), len(t)
273+
if n > m {
274+
return ""
275+
}
276+
need, window := make(map[byte]int), make(map[byte]int)
277+
needCount, windowCount := 0, 0
278+
for _, r := range t {
279+
if need[byte(r)] == 0 {
280+
needCount++
281+
}
282+
need[byte(r)]++
283+
}
284+
start, minLen := 0, math.MaxInt32
285+
left, right := 0, 0
286+
for right < m {
287+
ch := s[right]
288+
right++
289+
if v, ok := need[ch]; ok {
290+
window[ch]++
291+
if window[ch] == v {
292+
windowCount++
293+
}
294+
}
295+
for windowCount == needCount {
296+
if right-left < minLen {
297+
minLen = right - left
298+
start = left
299+
}
300+
ch = s[left]
301+
left++
302+
if v, ok := need[ch]; ok {
303+
if window[ch] == v {
304+
windowCount--
305+
}
306+
window[ch]--
307+
}
308+
}
309+
}
310+
if minLen == math.MaxInt32 {
311+
return ""
312+
}
313+
return s[start : start+minLen]
314+
}
76315
```
77316

78317
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// func minWindow(s string, t string) string {
2+
// m, n := len(s), len(t)
3+
// if n > m {
4+
// return ""
5+
// }
6+
// need, window := make(map[byte]int), make(map[byte]int)
7+
// for _, r := range t {
8+
// need[byte(r)]++
9+
// }
10+
// start, minLen := 0, math.MaxInt32
11+
// left, right := 0, 0
12+
// for right < m {
13+
// window[s[right]]++
14+
// right++
15+
// for check(need, window) {
16+
// if right-left < minLen {
17+
// minLen = right - left
18+
// start = left
19+
// }
20+
// window[s[left]]--
21+
// left++
22+
// }
23+
// }
24+
// if minLen == math.MaxInt32 {
25+
// return ""
26+
// }
27+
// return s[start : start+minLen]
28+
// }
29+
30+
// func check(need, window map[byte]int) bool {
31+
// for k, v := range need {
32+
// if window[k] < v {
33+
// return false
34+
// }
35+
// }
36+
// return true
37+
// }
38+
39+
func minWindow(s string, t string) string {
40+
m, n := len(s), len(t)
41+
if n > m {
42+
return ""
43+
}
44+
need, window := make(map[byte]int), make(map[byte]int)
45+
needCount, windowCount := 0, 0
46+
for _, r := range t {
47+
if need[byte(r)] == 0 {
48+
needCount++
49+
}
50+
need[byte(r)]++
51+
}
52+
start, minLen := 0, math.MaxInt32
53+
left, right := 0, 0
54+
for right < m {
55+
ch := s[right]
56+
right++
57+
if v, ok := need[ch]; ok {
58+
window[ch]++
59+
if window[ch] == v {
60+
windowCount++
61+
}
62+
}
63+
for windowCount == needCount {
64+
if right-left < minLen {
65+
minLen = right - left
66+
start = left
67+
}
68+
ch = s[left]
69+
left++
70+
if v, ok := need[ch]; ok {
71+
if window[ch] == v {
72+
windowCount--
73+
}
74+
window[ch]--
75+
}
76+
}
77+
}
78+
if minLen == math.MaxInt32 {
79+
return ""
80+
}
81+
return s[start : start+minLen]
82+
}

0 commit comments

Comments
 (0)