Skip to content

Commit ddd3676

Browse files
authored
Merge pull request #472 from haklee/main
[haklee] week 6
2 parents 5e24497 + 5e09250 commit ddd3676

File tree

4 files changed

+283
-0
lines changed

4 files changed

+283
-0
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
"""TC: O(n), SC: O(1)
2+
3+
아이디어:
4+
높이 리슀트 l이 μ£Όμ–΄μ‘Œλ‹€κ³  ν•˜μž. 그리고 이 μ•ˆμ— μžˆλŠ” μ΅œλŒ€ 수쑰 면적을 f(l)이라고 ν•˜μž.
5+
6+
β–‘ β–‘ β–‘
7+
β–‘ β–‘ β–‘ β–‘
8+
β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘
9+
β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘
10+
β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘
11+
2,5,3,3,1,3,1,2,2,5,3,5,3,4
12+
^
13+
l
14+
15+
16+
그러면 λ‹€μŒμ΄ 항상 μ„±λ¦½ν•œλ‹€.
17+
18+
- l의 μ–‘ 끝의 κ°’ 쀑 μž‘μ€ κ°’ xκ°€ μ•žμͺ½μ— μžˆμ—ˆλ‹€κ³  ν•΄λ³΄μž. xλ₯Ό λΊ€ 리슀트 l`을 λ§Œλ“ λ‹€.
19+
- μ΄λ•Œ μž‘μ€ 값이 λ’·μͺ½μ— μžˆμ—ˆμ–΄λ„ μΌλ°˜μ„±μ„ μžƒμ§€ μ•ŠλŠ”λ‹€.
20+
21+
β”‚β–‘ β–‘ β–‘
22+
β”‚β–‘ β–‘ β–‘ β–‘
23+
β”‚β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘
24+
β–‘β”‚β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘
25+
β–‘β”‚β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘
26+
2β”‚5,3,3,1,3,1,2,2,5,3,5,3,4
27+
^ ^
28+
x l`
29+
30+
31+
- f(l)은 κ·Έλ ‡λ‹€λ©΄
32+
- f(l`)μ΄κ±°λ‚˜(즉, xλ₯Ό μ“°μ§€ μ•Šμ•˜κ±°λ‚˜)
33+
- xλ₯Ό μ¨μ„œ λ§Œλ“  수쑰 면적 쀑에 μžˆλ‹€.
34+
35+
- 그런데 xλŠ” l의 μ–‘ 끝 κ°’ 쀑에 μž‘μ€ κ°’μ΄λ―€λ‘œ, μ•„λž˜μ™€ 같은 뢄석을 ν•  수 μžˆλ‹€.
36+
1) xλ₯Ό μ¨μ„œ λ§Œλ“œλŠ” 수쑰의 λ†’μ΄λŠ” 아무리 높아도 xλ‹€. x보닀 μž‘μ•„μ§ˆ μˆ˜λŠ” μžˆμ–΄λ„, x보닀 컀질 μˆ˜λŠ” μ—†λ‹€.
37+
2) xλ₯Ό μ¨μ„œ λ§Œλ“œλŠ” 수쑰의 폭은 l의 λ‹€λ₯Έμͺ½ 끝에 μžˆλŠ” 높이λ₯Ό μ„ νƒν–ˆμ„λ•Œ μ΅œλŒ€κ°€ λœλ‹€.
38+
- κ·ΈλŸ¬λ―€λ‘œ, xλ₯Ό μ¨μ„œ λ§Œλ“€ 수 μžˆλŠ” 수쑰의 μ΅œλŒ€ ν¬κΈ°λŠ” l의 λ‹€λ₯Έμͺ½ 끝에 μžˆλŠ” 높이λ₯Ό μ„ νƒν•œ 경우 λ‚˜μ˜¨λ‹€.
39+
40+
μœ„μ˜ λ‚΄μš©μ„ μ•„λž˜μ˜ μ„€λͺ…을 톡해 μ‹œκ°μ μœΌλ‘œ 확인할 수 μžˆλ‹€.
41+
42+
- μ–‘ 끝을 μ„ νƒν•œ 경우 x둜 λ§Œλ“€ 수 μžˆλŠ” μ΅œλŒ€ 면적이닀.
43+
44+
β”‚β–‘ β–‘ β–‘
45+
β”‚β–‘ β–‘ β–‘ β–‘
46+
β”‚β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘
47+
β– β”‚β–  β–  β–  β–  β–  β–  β–  β–  β–  β–  β–  β–  β– 
48+
β– β”‚β–  β–  β–  β–  β–  β–  β–  β–  β–  β–  β–  β–  β– 
49+
2β”‚5,3,3,1,3,1,2,2,5,3,5,3,4
50+
^ ^
51+
52+
- xλŠ” κ·ΈλŒ€λ‘œ λ‘” 채 λ‹€λ₯Έμͺ½ 끝을 μ•ˆμͺ½μœΌλ‘œ 더 μ΄λ™ν•˜λ©΄ 수쑰 λ†’μ΄λŠ” λ™μΌν•œλ° 폭은 더 μž‘μ•„μ§„λ‹€.
53+
54+
β”‚β–‘ β–‘ β–‘
55+
β”‚β–‘ β–‘ β–‘ β–‘
56+
β”‚β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘
57+
β– β”‚β–  β–  β–  β–  β–  β–  β–  β–  β–  β–  β–  β–‘ β–‘
58+
β– β”‚β–  β–  β–  β–  β–  β–  β–  β–  β–  β–  β–  β–‘ β–‘
59+
2β”‚5,3,3,1,3,1,2,2,5,3,5,3,4
60+
^ ^
61+
62+
- 심지어 x보닀 μž‘μ€ 높이 값을 μ„ νƒν•œ 경우 수쑰 높이도 μž‘μ•„μ§€κ³  폭도 μž‘μ•„μ§€λŠ” 일이 μΌμ–΄λ‚œλ‹€.
63+
64+
β”‚β–‘ β–‘ β–‘
65+
β”‚β–‘ β–‘ β–‘ β–‘
66+
β”‚β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘
67+
β–‘β”‚β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘
68+
β– β”‚β–  β–  β–  β–  β–  β–  β–‘ β–‘ β–‘ β–‘ β–‘ β–‘ β–‘
69+
2β”‚5,3,3,1,3,1,2,2,5,3,5,3,4
70+
71+
72+
즉, μœ„μ˜ λ‚΄μš©μ„ μ’…ν•©ν•˜λ©΄ λ‹€μŒμ„ 확인할 수 μžˆλ‹€.
73+
- f(l) = max( (l의 μ–‘ 끝 높이λ₯Ό μ„ νƒν•΄μ„œ λ§Œλ“  수쑰 넓이), f(l`) )
74+
- 그런데 f(l`)도 f(l)을 κ΅¬ν•œ 것과 같은 λ°©μ‹μœΌλ‘œ ꡬ할 수 μžˆλ‹€. 즉, μƒˆλ‘œ λ§Œλ“€μ–΄μ§„ l`의 μ–‘ 끝 높이 쀑
75+
짧은 μͺ½μ„ λΊ€ 리슀트 l``을 λ§Œλ“€μ–΄μ„œ μœ„μ˜ 과정을 λ°˜λ³΅ν•  수 μžˆλ‹€.
76+
- 즉, f(l)은 μ•„λž˜μ˜ 과정을 λ°˜λ³΅ν•˜μ—¬ ꡬ할 수 μžˆλ‹€.
77+
- l의 μ–‘ 끝 높이λ₯Ό μ¨μ„œ 수쑰 넓이λ₯Ό κ΅¬ν•˜κ³ , κΈ°μ‘΄ μ΅œλŒ€ 넓이와 λΉ„κ΅ν•˜μ—¬ 더 큰 값을 μ΅œλŒ€ 넓이에 λŒ€μž…ν•œλ‹€.
78+
- lμ—μ„œ 짧은 μͺ½ 높이λ₯Ό λΊ€λ‹€.
79+
- μœ„ 과정을 l에 μ•„μ΄ν…œμ΄ ν•˜λ‚˜λ§Œ 남을 λ•ŒκΉŒμ§€ 반볡.
80+
81+
82+
SC:
83+
- 투 포인터λ₯Ό μ¨μ„œ l의 μ‹œμž‘, 끝 인덱슀λ₯Ό κ΄€λ¦¬ν•˜λ©΄ O(1).
84+
- 수쑰 μ΅œλŒ€ 넓이값 관리, O(1).
85+
- μ’…ν•©ν•˜λ©΄ O(1).
86+
87+
TC:
88+
- 리슀트의 μ–‘ 끝 높이λ₯Ό 톡해 면적 κ΅¬ν•˜κΈ°, O(1).
89+
- 포인터 이동 O(1).
90+
- 포인터 μ΄λ™μ‹œ 두 포인터 μ‚¬μ΄μ˜ 거리가 1μ”© 항상 κ°μ†Œν•˜λ―€λ‘œ μœ„ 과정을 μ΅œλŒ€ n-2번 반볡.
91+
- μ’…ν•©ν•˜λ©΄ O(n).
92+
"""
93+
94+
95+
class Solution:
96+
def maxArea(self, height: List[int]) -> int:
97+
max_area = -1
98+
s, e = 0, len(height) - 1
99+
while s < e:
100+
max_area = max(max_area, (e - s) * min(height[s], height[e]))
101+
if height[s] > height[e]:
102+
e -= 1
103+
else:
104+
s += 1
105+
return max_area
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
"""searchμ‹œ: TC: O(n), SC: O(n)
2+
3+
word의 max lengthκ°€ w, `addWord`λ₯Ό 톡해 λ§Œλ“€μ–΄μ§„ λ…Έλ“œ κ°œμˆ˜κ°€ n개라고 ν•˜μž.
4+
5+
아이디어:
6+
`implement-trie-prefix-tree` λ¬Έμ œμ—μ„œ κ΅¬ν˜„ν•œ trieμ—μ„œ search λΆ€λΆ„λ§Œ recursiveν•œ dfs κ΅¬ν˜„μœΌλ‘œ μˆ˜μ •.
7+
8+
SC:
9+
- trie의 λ…Έλ“œ 개수 O(n).
10+
- dfsμ‹œ μŠ€νƒ κΉŠμ΄λŠ” μ΅œλŒ€ w. 즉, O(w). 그런데 μŠ€νƒ κΉŠμ΄λŠ” λ…Έλ“œ κ°œμˆ˜λ³΄λ‹€ 클 수 μ—†λ‹€. 즉, O(w) < O(n).
11+
- μ’…ν•©ν•˜λ©΄, O(n) + O(w) < O(n) + O(n) = O(n).
12+
13+
TC:
14+
- μ΅œμ•…μ˜ 경우 λͺ¨λ“  λ…Έλ“œ 순회. O(n).
15+
16+
"""
17+
18+
19+
class WordDictionary:
20+
21+
def __init__(self):
22+
self.next: dict[str, WordDictionary] = {}
23+
self.end: bool = False
24+
25+
def addWord(self, word: str) -> None:
26+
cur = self
27+
28+
for c in word:
29+
cur.next[c] = cur.next.get(c, WordDictionary())
30+
cur = cur.next[c]
31+
32+
cur.end = True
33+
34+
def search(self, word: str) -> bool:
35+
cur = self
36+
37+
return self._search(cur, word, 0)
38+
39+
def _search(self, trie, word: str, ind: int) -> bool:
40+
if ind == len(word):
41+
return trie.end
42+
43+
c = word[ind]
44+
45+
if c == ".":
46+
return any(
47+
[self._search(node, word, ind + 1) for node in trie.next.values()]
48+
)
49+
50+
if c not in trie.next:
51+
return False
52+
53+
return self._search(trie.next[c], word, ind + 1)
54+
55+
56+
# Your WordDictionary object will be instantiated and called as such:
57+
# obj = WordDictionary()
58+
# obj.addWord(word)
59+
# param_2 = obj.search(word)

β€Žspiral-matrix/haklee.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
"""searchμ‹œ: TC: O(m*n), SC: O(1)
2+
3+
아이디어:
4+
2차원 λ°°μ—΄μ—μ„œ 아직 ν›‘κ³  κ°€μ§€ μ•Šμ€ μ˜μ—­μ„ β†’, ↓, ←, ↑ λ°©ν–₯으둜 ν›‘λŠ”λ‹€. μ΄λ•Œ, ν•œ λ²ˆμ— ν›‘κ³  갈 μ„ μ˜
5+
μ‹œμž‘κ³Ό 끝 역할을 ν•  κ°’λ“€(즉, boundary κ°’λ“€)을 잘 관리해쀀닀.
6+
- top, bottom, left, right의 역할을 ν•  값을 각각 0, m, 0, n으둜 μ΄ˆκΈ°ν™”.
7+
- β†’ λ°©ν–₯으둜 ν›‘κ³  λ‚˜μ„œ top을 ν•œ μΉΈ μ•„λž˜λ‘œ(즉, top++).
8+
- ↓ λ°©ν–₯으둜 ν›‘κ³  λ‚˜μ„œ rightλ₯Ό ν•œ μΉΈ μ™Όμͺ½μœΌλ‘œ(즉, right--).
9+
- ← λ°©ν–₯으둜 ν›‘κ³  λ‚˜μ„œ bottom을 ν•œ μΉΈ μœ„λ‘œ(즉, bottom--).
10+
- ↑ λ°©ν–₯으둜 ν›‘κ³  λ‚˜μ„œ leftλ₯Ό ν•œ μΉΈ 였λ₯Έμͺ½μœΌλ‘œ(즉, left++).
11+
- rightκ°€ left보닀 μ™Όμͺ½μ— μžˆκ±°λ‚˜ top이 bottom보닀 μ•„λž˜ 있으면 탐색 μ’…λ£Œ.
12+
13+
SC:
14+
- boundary κ°’λ§Œ 관리. O(1).
15+
16+
TC:
17+
- λ°°μ—΄μ˜ λͺ¨λ“  μ•„μ΄ν…œμ— μ •ν™•νžˆ ν•œ λ²ˆμ”© μ ‘κ·Ό. O(m*n).
18+
- 선을 ν•œ 번 κΈ‹λŠ” κ³Όμ •μ—μ„œ μΌμ–΄λ‚˜λŠ” 일이 총 O(1)인데(μ½”λ“œ μ°Έμ‘°), 이게 아무리 λ§Žμ•„λ„ O(m*n)을 λ„˜μ§€λŠ”
19+
λͺ»ν•œλ‹€. ν•œ 선에 μ΅œμ†Œ ν•˜λ‚˜μ˜ 값은 λ“€μ–΄μžˆκΈ° λ•Œλ¬Έ.
20+
- μ’…ν•©ν•˜λ©΄ O(m*n).
21+
22+
"""
23+
24+
25+
class Solution:
26+
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
27+
def read_line(start: tuple[int, int], end: tuple[int, int]) -> list[int]:
28+
if start[0] == end[0]:
29+
# column λ°©ν–₯
30+
s, e = sorted([start[1], end[1]]) # TC: O(1)
31+
line = range(s, e + 1)
32+
if start[1] > end[1]: # TC: O(1)
33+
line = reversed(line)
34+
return [matrix[i][start[0]] for i in line]
35+
else:
36+
# row λ°©ν–₯
37+
s, e = sorted([start[0], end[0]]) # TC: O(1)
38+
line = range(s, e + 1)
39+
if start[0] > end[0]: # TC: O(1)
40+
line = reversed(line)
41+
return [matrix[start[1]][i] for i in line]
42+
43+
top, bottom, left, right = 0, len(matrix) - 1, 0, len(matrix[0]) - 1
44+
sol = []
45+
while True:
46+
# μœ„
47+
if right < left:
48+
break
49+
line = read_line((left, top), (right, top))
50+
sol += line
51+
top += 1 # TC: O(1)
52+
53+
# 였λ₯Έμͺ½
54+
if top > bottom:
55+
break
56+
line = read_line((right, top), (right, bottom))
57+
sol += line
58+
right -= 1 # TC: O(1)
59+
60+
# μ•„λž˜
61+
if right < left:
62+
break
63+
line = read_line((right, bottom), (left, bottom))
64+
sol += line
65+
bottom -= 1 # TC: O(1)
66+
67+
# μ™Όμͺ½
68+
if top > bottom:
69+
break
70+
line = read_line((left, bottom), (left, top))
71+
sol += line
72+
left += 1 # TC: O(1)
73+
74+
return sol

β€Žvalid-parentheses/haklee.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
"""TC: O(n), SC: O(n)
2+
3+
λ¬Έμžμ—΄ 길이 n
4+
5+
아이디어:
6+
- λ¬Έμžμ—΄μ„ μ•žμ—μ„œλΆ€ν„° ν›‘μœΌλ©΄μ„œ
7+
- κ΄„ν˜Έ μ‹œμž‘μ„ λ°œκ²¬ν•˜λ©΄ μŠ€νƒμ— λ„£λŠ”λ‹€.
8+
- κ΄„ν˜Έ 끝을 λ°œκ²¬ν•˜λ©΄ μŠ€νƒμ˜ 제일 λ§ˆμ§€λ§‰μ— μžˆλŠ” μ•„μ΄ν…œμ„ popν•΄μ„œ 맀칭이 λ˜λŠ”μ§€ ν™•μΈν•œλ‹€.
9+
- μ΄λ•Œ λ‹€μŒκ³Ό 같은 μ˜ˆμ™Έ 상황듀을 μ‘°μ‹¬ν•œλ‹€.
10+
- μŠ€νƒμ— μ•„μ΄ν…œμ΄ ν•˜λ‚˜λ„ μ—†λŠ”λ° pop을 ν•˜λ €λŠ” 상황 λ°©μ§€.
11+
- e.g.) "))))"
12+
- λͺ¨λ“  λ¬Έμžμ—΄μ„ ν›‘κ³  μ§€λ‚˜κ°”λŠ”λ° μŠ€νƒμ— μ•„μ΄ν…œμ΄ λ‚¨μ•„μžˆλŠ” κ²½μš°λ„ μ‹€νŒ¨λ‹€.
13+
- e.g.) "(((("
14+
15+
SC:
16+
- μ‹œμž‘ κ΄„ν˜Έ 리슀트 O(1).
17+
- 끝 κ΄„ν˜Έμ™€ λ§€μΉ­λ˜λŠ” μ‹œμž‘ κ΄„ν˜Έ dict O(1).
18+
- μ‹œμž‘ κ΄„ν˜Έλ§Œ μžˆλŠ” 경우 μŠ€νƒμ— μŒ“μ΄λŠ” μ•„μ΄ν…œμ€ 총 nκ°œλ‹€. O(n).
19+
- μ’…ν•©ν•˜λ©΄ O(n).
20+
21+
TC:
22+
- 문자 총 nκ°œμ— λŒ€ν•΄ μ•„λž˜λ₯Ό λ°˜λ³΅ν•œλ‹€.
23+
- μ‹œμž‘ κ΄„ν˜ΈμΈμ§€ 체크. O(1).
24+
- μ‹œμž‘ κ΄„ν˜ΈμΈ 경우 μŠ€νƒμ— μŒ“κΈ° O(1).
25+
- 끝 κ΄„ν˜ΈμΈ 경우 μŠ€νƒμ—μ„œ popν• λ•Œ O(1), κ΄„ν˜Έ λ§€μΉ­ μ²΄ν¬μ‹œ O(1).
26+
- μ’…ν•©ν•˜λ©΄ O(n).
27+
"""
28+
29+
30+
class Solution:
31+
def isValid(self, s: str) -> bool:
32+
stack = []
33+
openings = ["(", "{", "["]
34+
ending_match = {
35+
")": "(",
36+
"}": "{",
37+
"]": "[",
38+
}
39+
for c in s:
40+
if c in openings:
41+
stack.append(c)
42+
else:
43+
if not stack or ending_match[c] != stack.pop():
44+
return False
45+
return False if stack else True

0 commit comments

Comments
Β (0)