|
| 1 | +class Solution: |
| 2 | + """ |
| 3 | + 접근 방법: https://www.youtube.com/watch?v=jSto0O4AJbM |
| 4 | + - t의 문자 개수를 미리 세어둔 후(t_count), |
| 5 | + s에서 두 포인터(left, right)를 이용해 슬라이딩 윈도우를 확장/축소하며 |
| 6 | + 모든 조건을 만족하는 최소 구간을 찾는다. |
| 7 | + - have: 현재 window에서 조건을 만족한 문자 종류 개수 |
| 8 | + - need: t에 있는 문자 종류 개수 |
| 9 | + - 조건을 만족할 때마다 왼쪽 포인터를 줄여 최소 길이 갱신 |
| 10 | +
|
| 11 | + 시간복잡도: |
| 12 | + - 각 문자를 오른쪽 포인터로 한 번, 왼쪽 포인터로 한 번만 방문 → O(|s|) |
| 13 | + - t의 해시맵 구성 O(|t|) |
| 14 | + - 최종 시간복잡도 = O(|s| + |t|) |
| 15 | +
|
| 16 | + 공간복잡도: |
| 17 | + - window와 t_count 해시맵 → O(|s| + |t|) |
| 18 | + """ |
| 19 | + def minWindow(self, s: str, t: str) -> str: |
| 20 | + t_count, window = {}, {} |
| 21 | + |
| 22 | + for c in t: |
| 23 | + t_count[c] = 1 + t_count.get(c, 0) |
| 24 | + |
| 25 | + have, need = 0, len(t_count) |
| 26 | + res, len_res = [-1, -1], float("infinity") |
| 27 | + left = 0 |
| 28 | + for right in range(len(s)): |
| 29 | + c = s[right] |
| 30 | + window[c] = 1 + window.get(c, 0) |
| 31 | + |
| 32 | + if c in t_count and window[c] == t_count[c]: |
| 33 | + have += 1 |
| 34 | + |
| 35 | + while have == need: |
| 36 | + if (right - left + 1) < len_res: |
| 37 | + res = [left, right] |
| 38 | + len_res = (right - left + 1) |
| 39 | + window[s[left]] -= 1 |
| 40 | + if s[left] in t_count and window[s[left]] < t_count[s[left]]: |
| 41 | + have -= 1 |
| 42 | + left += 1 |
| 43 | + left, right = res |
| 44 | + return s[left:right+1] if len_res != float("infinity") else "" |
0 commit comments