Skip to content

[i-mprovising] Week 06 solutions #1436

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions container-with-most-water/i-mprovising.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""
Time complexity O(n)
Space complexity O(1)

Two pointer
"""

class Solution:
def maxArea(self, height: List[int]) -> int:
s, e = 0, len(height) - 1
area = 0 # max area
while s < e:
h = min(height[s], height[e])
tmp = h * (e - s) # area at current iteration
area = max(area, tmp)
# move pointer
if height[s] < height[e]:
s += 1
else:
e -= 1

return area
44 changes: 44 additions & 0 deletions design-add-and-search-words-data-structure/i-mprovising.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""
Time complexity O(26^w)
Space complexity O(w)

Trie, DFS
"""

class Node:
def __init__(self, end=False):
self.children = {} # char : node
self.end = end

class WordDictionary:

def __init__(self):
self.root = Node(end=True)

def addWord(self, word: str) -> None:
node = self.root
for ch in word:
if ch not in node.children:
node.children[ch] = Node()
node = node.children[ch]
node.end = True

def search(self, word: str) -> bool:
return self.dfs(self.root, word)

def dfs(self, start, word):
ch = word[0]
if ch == word:
if ch == '.':
return any([node.end for node in start.children.values()])
elif ch in start.children:
if start.children[ch].end:
return True
return False

if ch == '.':
return any([self.dfs(node, word[1:]) for c, node in start.children.items()])
elif ch in start.children:
return self.dfs(start.children[ch], word[1:])
else:
return False
29 changes: 29 additions & 0 deletions longest-increasing-subsequence/i-mprovising.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""
Time complexity O(n^2)
Space complexity O(n)

Dynamic programming
"""

class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:

dp = [(1, nums[0])] # sequence len, max num in sequence

for i in range(1, len(nums)):
num = nums[i]
max_len = 1
for j in range(i):
x, y = dp[j]
if y < num:
if max_len < x + 1:
max_len = x + 1
dp.append((max_len, num))

# find max len
max_len = 0
for x in dp:
if x[0] > max_len:
max_len = x[0]

return max_len
60 changes: 60 additions & 0 deletions spiral-matrix/i-mprovising.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""
Time complexity O(m*n)

단순구현
"""

class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
"""
111
1M1 visited
111
"""
m, n = len(matrix), len(matrix[0])

board = [[0] * (n+2)]
for i in range(m):
tmp = [0] + matrix[i] + [0]
board.append(tmp)
board.append([0] * (n+2))

visited = [[True] * (n+1)]
for _ in range(m):
tmp = [True] + [False] * n + [True]
visited.append(tmp)
visited.append([True] * (n+1))

direction = 0
x, y = 1, 1
numbers = []

for _ in range(m * n):
numbers.append(board[x][y])
visited[x][y] = True

i, j = self.next_idx(direction, x, y)
if visited[i][j]:
direction = self.change_dir(direction)
x, y = self.next_idx(direction, x, y)
else:
x, y = i, j
Comment on lines +16 to +41
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

board 와 visited 배열을 활용하여 이렇게 풀 수도 있군요! 게다가 방향(direction)과 다음 인덱스 (next_idx)값을 명확하게 알 수 있어서 디버깅도 편리할 것 같네요ㅎㅎ

'경계값 pointer' 또는 '행/열 인덱스 pointer'를 사용하면 visited 배열을 따로 사용하지 않아도 되는데

https://www.algodale.com/problems/spiral-matrix/

궁금하시면 달레님 풀이를 한 번 확인해보셔도 좋을 것 같습니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

포인터 활용이 더 효율적인 것 같네요! 상세한 피드백 감사합니다 👍


return numbers

def next_idx(self, dir, x, y):
"""
0 1 2 3 : R D L U
"""
if dir == 0:
y += 1
elif dir == 1:
x += 1
elif dir == 2:
y -= 1
else:
x -= 1
return x, y

def change_dir(self, dir):
return (dir + 1) % 4
22 changes: 22 additions & 0 deletions valid-parentheses/i-mprovising.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""
Time complexity O(n)

stack
"""
class Solution:
def isValid(self, s: str) -> bool:
open_brackets = ["(", "{", "["]
bracket_map = {"(":")", "{":"}", "[":"]"}
stack = []
for char in s:
if char in open_brackets:
stack.append(char)
continue
if not stack:
return False
open_b = stack.pop() # last in open bracket
if bracket_map[open_b] != char:
return False
if stack:
return False
return True