Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 92b8ff2

Browse files
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‎

Lines changed: 240 additions & 1 deletion
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
### **...**
Lines changed: 82 additions & 0 deletions
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)

AltStyle によって変換されたページ (->オリジナル) /