Skip to content

Commit 182ac06

Browse files
authored
Merge pull request #1637 from KwonNayeon/main
[KwonNayeon] Week 14 Solutions
2 parents 5726dc5 + cc59421 commit 182ac06

File tree

3 files changed

+133
-12
lines changed

3 files changed

+133
-12
lines changed

find-median-from-data-stream/KwonNayeon.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
- There will be at least one element in the data structure before calling findMedian.
55
- At most 5 * 10^4 calls will be made to addNum and findMedian.
66
7+
<Solution 1: 리스트 활용>
8+
79
Time Complexity:
810
- addNum(): O(nlogn)
911
- 매번 정렬하기 때문
@@ -41,3 +43,54 @@ def findMedian(self) -> float:
4143
mid2 = self.nums[n // 2]
4244
return (mid1 + mid2) / 2.0
4345

46+
"""
47+
<Solution 2: 힙 활용>
48+
49+
Time Complexity:
50+
- addNum(): O(log n) - 힙에 삽입/삭제 연산
51+
- findMedian(): O(1) - 힙의 루트 요소만 접근
52+
53+
Space Complexity:
54+
- O(n) - 모든 입력 숫자를 두 개의 힙에 저장
55+
56+
풀이방법:
57+
max/min heap을 사용해서 데이터를 절반씩 나누어 median 값을 찾음
58+
1. 자료구조
59+
- lower (max heap)
60+
- upper (min heap)
61+
2. addNum
62+
- upper가 비어있거나 새로운 숫자가 upper[0]보다 크면 upper에 추가
63+
- 그렇지 않으면 lower에 추가
64+
3. 균형 유지
65+
- 두 힙의 크기 차이가 최대 1이 되도록 조정함
66+
- lower가 더 많으면 upper로 이동
67+
- upper가 2개 이상 더 많으면 lower로 이동
68+
4. 중간값 계산
69+
- 홀수개: upper[0] (upper가 항상 1개 더 많거나 같기 때문)
70+
- 짝수개: (-lower[0] + upper[0]) / 2
71+
"""
72+
from heapq import heappop, heappush
73+
74+
class MedianFinder:
75+
76+
def __init__(self):
77+
self.lower = []
78+
self.upper = []
79+
80+
def addNum(self, num: int) -> None:
81+
if not self.upper or self.upper[0] < num:
82+
heappush(self.upper, num)
83+
else:
84+
heappush(self.lower, -num)
85+
86+
if len(self.lower) > len(self.upper):
87+
heappush(self.upper, -heappop(self.lower))
88+
elif len(self.lower) + 1 < len(self.upper):
89+
heappush(self.lower, -heappop(self.upper))
90+
91+
def findMedian(self) -> float:
92+
if len(self.lower) < len(self.upper):
93+
return self.upper[0]
94+
95+
else:
96+
return (-self.lower[0] + self.upper[0]) / 2

word-search-ii/KwonNayeon.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
"""
2+
Constraints:
3+
- m == board.length
4+
- n == board[i].length
5+
- 1 <= m, n <= 12
6+
- board[i][j] is a lowercase English letter.
7+
- 1 <= words.length <= 3 * 10^4
8+
- 1 <= words[i].length <= 10
9+
- words[i] consists of lowercase English letters.
10+
- All the strings of words are unique.
11+
12+
Time Complexity: O(W * N * 4^L)
13+
- W는 words의 개수
14+
- N은 board의 모든 cell (m * n)
15+
- L은 word의 길이
16+
- 각 단어마다 Word Search 1을 반복
17+
18+
Space Complexity: O(L)
19+
- L은 word의 길이로, 재귀 호출 스택의 깊이
20+
21+
Word search 1과의 차이점:
22+
- 단어 여러개를 동시에 찾아야 함
23+
- 찾은 모든 단어들을 리스트로 반환해야 함
24+
25+
풀이방법:
26+
- Word search 1과 동일한 방법 + set(words)로 중복 제거
27+
28+
노트:
29+
- 시간초과로 통과 안 됨
30+
- Trie 자료구조로 다시 풀어보기
31+
"""
32+
class Solution:
33+
def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
34+
words = list(set(words))
35+
result = []
36+
37+
def exist(word):
38+
rows, cols = len(board), len(board[0])
39+
40+
def dfs(i, j, k):
41+
if k == len(word):
42+
return True
43+
44+
if (i < 0 or i >= rows or
45+
j < 0 or j >= cols or
46+
board[i][j] != word[k]):
47+
return False
48+
49+
temp = board[i][j]
50+
board[i][j] = '#'
51+
52+
result = (dfs(i+1, j, k+1) or
53+
dfs(i-1, j, k+1) or
54+
dfs(i, j+1, k+1) or
55+
dfs(i, j-1, k+1))
56+
57+
board[i][j] = temp
58+
return result
59+
60+
for i in range(rows):
61+
for j in range(cols):
62+
if board[i][j] == word[0]:
63+
if dfs(i, j, 0):
64+
return True
65+
return False
66+
67+
for word in words:
68+
if exist(word):
69+
result.append(word)
70+
return result

word-search/KwonNayeon.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,41 +6,39 @@
66
4. word length is between 1 and 15 inclusive
77
5. board and word contain only lowercase and uppercase English letters
88
9-
Time Complexity: O(N * 3^L)
9+
Time Complexity: O(N * 4^L)
1010
- N은 board의 모든 cell (m * n)
1111
- L은 word의 길이
12-
- 각 cell에서 시작하여 word의 각 글자마다 세방향으로 탐색 (이미 방문한 방향 제외)
12+
- 각 cell에서 시작하여 word의 각 글자마다 네방향으로 탐색 (이미 방문한 방향 제외)
1313
1414
Space Complexity: O(L)
1515
- L은 word의 길이로, 재귀 호출 스택의 깊이
16-
17-
To Do:
18-
- DFS와 백트래킹 개념 복습하기
19-
- 다른 스터디원분들의 답안 참조하여 다른 풀이방법 복습하기
2016
"""
2117

2218
class Solution:
2319
def exist(self, board: List[List[str]], word: str) -> bool:
2420
rows, cols = len(board), len(board[0])
2521

2622
def dfs(i, j, k):
23+
24+
# 단어를 모두 찾았으면 True 반환
2725
if k == len(word):
2826
return True
2927

30-
if (i < 0 or i >= rows or
28+
if (i < 0 or i >= rows or # 경계체크
3129
j < 0 or j >= cols or
32-
board[i][j] != word[k]):
30+
board[i][j] != word[k]): # 현재 문자가 찾는 문자와 다름
3331
return False
3432

35-
temp = board[i][j]
36-
board[i][j] = '#'
33+
temp = board[i][j] # 현재 문자를 임시저장
34+
board[i][j] = '#' # 방문 표시
3735

38-
result = (dfs(i+1, j, k+1) or
36+
result = (dfs(i+1, j, k+1) or # 상하좌우 네 방향 탐색
3937
dfs(i-1, j, k+1) or
4038
dfs(i, j+1, k+1) or
4139
dfs(i, j-1, k+1))
4240

43-
board[i][j] = temp
41+
board[i][j] = temp # 백트래킹 (원래 문자로 복원)
4442
return result
4543

4644
for i in range(rows):

0 commit comments

Comments
 (0)