Skip to content

Commit 981685e

Browse files
committed
solve(w09): 76. Minimum Window Substring
1 parent 10b7564 commit 981685e

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# https://leetcode.com/problems/minimum-window-substring/
2+
3+
class Solution:
4+
def minWindow1(self, s: str, t: str) -> str:
5+
"""
6+
[Complexity]
7+
- TC: O(m * k + n) (k = is_included() = len(set(t)))
8+
- SC: O(k)
9+
10+
[Approach]
11+
๋‹ค์Œ๊ณผ ๊ฐ™์€ counter๋ฅผ ์œ ์ง€ํ•˜๋ฉฐ, two pointer๋กœ window๋ฅผ ์ด๋™ํ•˜๋ฉฐ min window substring์„ ํŠธ๋ž˜ํ‚นํ•œ๋‹ค.
12+
- ์ƒ์„ฑ ์‹œ) t์˜ ๋ชจ๋“  ๋ฌธ์ž์— ๋Œ€ํ•ด ++
13+
- pointer ์ด๋™ ์‹œ) window์— ํฌํ•จ๋˜๋Š” ๋ฌธ์ž ์ค‘ t์— ์†ํ•˜๋Š” ๋ฌธ์ž์— ๋Œ€ํ•ด --
14+
"""
15+
m, n = len(s), len(t)
16+
17+
# early stop
18+
if m < n:
19+
return ""
20+
21+
# t์— ๋Œ€ํ•œ counter ์ƒ์„ฑ
22+
counter = {}
23+
for _t in t:
24+
if _t not in counter:
25+
counter[_t] = 0
26+
counter[_t] += 1
27+
28+
# t์˜ ๋ชจ๋“  ๋ฌธ์ž๊ฐ€ window์— ํฌํ•จ๋˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ํ•จ์ˆ˜
29+
def is_included():
30+
# counter์˜ ๋ชจ๋“  ๊ฐ’์ด 0 ์ดํ•˜์ด๋ฉด, t์˜ ๋ชจ๋“  ๋ฌธ์ž๊ฐ€ window์— ํฌํ•จ๋˜๋Š” ๊ฒƒ (์ค‘๋ณต ํฌํ•จ)
31+
return all(c <= 0 for c in counter.values())
32+
33+
lo, min_len = 0, 1e6
34+
res = ""
35+
36+
for hi in range(m):
37+
# ํ˜„์žฌ window์— ํฌํ•จ๋œ ๋ฌธ์ž๋ฅผ counter์— ๋ฐ˜์˜
38+
if s[hi] in counter:
39+
counter[s[hi]] -= 1
40+
41+
# t์˜ ๋ชจ๋“  ๋ฌธ์ž๊ฐ€ window์— ํฌํ•จ๋˜์–ด์žˆ๋‹ค๋ฉด(= counter์˜ ๋ชจ๋“  ๊ฐ’์ด <= 0์ด๋ฉด),
42+
# counter ๊ฐ’์ด ์Œ์ˆ˜ ~ 0์ด ๋  ๋•Œ๊นŒ์ง€ lo ์ฆ๊ฐ€์‹œํ‚ค๋ฉด์„œ (min window๋ฅผ ๊ตฌํ•ด์•ผํ•˜๋ฏ€๋กœ) counter ์—…๋ฐ์ดํŠธ
43+
if is_included():
44+
while True:
45+
# window์˜ ์ฒซ ๋ฒˆ์งธ ๋ฌธ์ž๊ฐ€ t์— ์†ํ•˜๋Š” ๋ฌธ์ž๋ผ๋ฉด
46+
if s[lo] in counter:
47+
# counter์—์„œ์˜ ๊ฐ’์ด 0์ด๋ฉด, ๋”์ด์ƒ lo๋ฅผ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ค„์ผ ์ˆ˜ ์—†์Œ
48+
if counter[s[lo]] == 0:
49+
break
50+
# coutner์—์„œ์˜ ๊ฐ’์ด ์Œ์ˆ˜๋ผ๋ฉด, lo๋ฅผ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ค„์ผ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ counter ๋ฐ˜์˜
51+
else:
52+
counter[s[lo]] += 1
53+
# lo๋ฅผ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ํ•œ ์นธ ์ด๋™
54+
lo += 1
55+
56+
# (1) t์˜ ๋ชจ๋“  ๋ฌธ์ž๊ฐ€ window์— ํฌํ•จ๋˜์–ด ์žˆ๊ณ  (2) ํ˜„์žฌ window์˜ length๊ฐ€ min_len ๋ณด๋‹ค ์ž‘๋‹ค๋ฉด
57+
# window substring ์—…๋ฐ์ดํŠธ
58+
if is_included() and (new_len := hi - lo + 1) < min_len:
59+
min_len = new_len
60+
res = s[lo:hi + 1]
61+
62+
return res
63+
64+
def minWindow(self, s: str, t: str) -> str:
65+
"""
66+
[Complexity]
67+
- TC: O(m + n)
68+
- SC: O(k)
69+
70+
[Approach]
71+
์œ„์˜ ํ’€์ด์—์„œ is_included()๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐ์— O(k)์ด ์†Œ์š”๋˜๋ฏ€๋กœ,
72+
(t์— ์†ํ•˜๋Š” ๋ฌธ์ž ์ค‘, ํ˜„์žฌ window์— ๋ชจ๋‘ ํฌํ•จ๋˜๋Š” ๋ฌธ์ž์˜ ์ข…๋ฅ˜ ๊ฐœ์ˆ˜)๋ฅผ ํŠธ๋ž˜ํ‚นํ•˜๋Š” ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ์ตœ์ ํ™” ํ•œ๋‹ค.
73+
์ฆ‰, have == len(counter)๋ผ๋ฉด is_included()์ธ ๊ฒƒ๊ณผ ๋™์ผํ•˜๋‹ค.
74+
"""
75+
m, n = len(s), len(t)
76+
77+
# early stop
78+
if m < n:
79+
return ""
80+
81+
# t์— ๋Œ€ํ•œ counter ์ƒ์„ฑ
82+
counter = {}
83+
for _t in t:
84+
if _t not in counter:
85+
counter[_t] = 0
86+
counter[_t] += 1
87+
88+
# counter์˜ ๊ฐ’์„ ๋ชจ๋‘ ํ™•์ธํ•˜๋Š” is_include() ์ตœ์ ํ™”
89+
# have = t์— ์†ํ•˜๋Š” ๋ฌธ์ž ์ค‘, ํ˜„์žฌ window์— ๋ชจ๋‘ ํฌํ•จ๋˜๋Š” ๋ฌธ์ž์˜ ์ข…๋ฅ˜ ๊ฐœ์ˆ˜
90+
# have == need๋ผ๋ฉด, is_included() ์ธ ๊ฒƒ๊ณผ ๊ฐ™์Œ
91+
have, need = 0, len(counter)
92+
lo, min_len = 0, 1e6
93+
res = ""
94+
95+
for hi in range(m):
96+
# ํ˜„์žฌ window์— ํฌํ•จ๋œ ๋ฌธ์ž๋ฅผ counter์— ๋ฐ˜์˜
97+
if s[hi] in counter:
98+
counter[s[hi]] -= 1
99+
# ํ˜„์žฌ window์— ํ•ด๋‹น ๋ฌธ์ž๊ฐ€ t์— ์กด์žฌํ•˜๋Š” ๊ฐœ์ˆ˜๋งŒํผ ๋“ค์–ด์™€์žˆ๋‹ค๋ฉด, have++
100+
if counter[s[hi]] == 0:
101+
have += 1
102+
103+
# t์˜ ๋ชจ๋“  ๋ฌธ์ž๊ฐ€ window์— ํฌํ•จ๋˜์–ด์žˆ๋Š” ๋™์•ˆ lo ์ด๋™
104+
while have == need:
105+
# ์ตœ์†Œ ๊ธธ์ด window substring ๊ฐฑ์‹ 
106+
if (new_len := hi - lo + 1) < min_len:
107+
min_len = new_len
108+
res = s[lo:hi + 1]
109+
110+
# lo ์ด๋™ ์ „, counter ์—…๋ฐ์ดํŠธ
111+
if s[lo] in counter:
112+
counter[s[lo]] += 1
113+
# counter์˜ ๊ฐ’์ด 0 ์ดˆ๊ณผ๊ฐ€ ๋œ๋‹ค๋ฉด, ๋”์ด์ƒ window์— ํ•ด๋‹น ๋ฌธ์ž๊ฐ€ ๋ชจ๋‘ ๋“ค์–ด์žˆ์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์ด๋ฏ€๋กœ have--
114+
if counter[s[lo]] > 0:
115+
have -= 1
116+
117+
# lo๋ฅผ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ํ•œ ์นธ ์ด๋™
118+
lo += 1
119+
120+
return res

0 commit comments

Comments
ย (0)