Skip to content

[Chaedie] Week 6 #897

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 9 commits into from
Jan 19, 2025
43 changes: 43 additions & 0 deletions container-with-most-water/Chaedie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""
Solution: Brute Force
Time: O(n^2)
Space: O(1)
"""


class Solution:
def maxArea(self, height: List[int]) -> int:
max_water = 0
for i in range(len(height) - 1):
for j in range(i + 1, len(height)):
h = min(height[i], height[j])
w = j - i
max_water = max(h * w, max_water)

return max_water


"""
Solution: Two Pointer
1) 포인터 이동은 left height, right height 중 작은 value를 가질 경우 이동
Time: O(n)
Space: O(1)
"""


class Solution:
def maxArea(self, height: List[int]) -> int:
l = 0
r = len(height) - 1
max_water = 0

while l < r:
h = min(height[l], height[r])
w = r - l
max_water = max(h * w, max_water)

if height[l] < height[r]:
l += 1
else:
r -= 1
return max_water
112 changes: 112 additions & 0 deletions design-add-and-search-words-data-structure/Chaedie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
"""
풀이를 보고 공부했습니다.

Solution:
set을 이용,
1) addWord 에선 add
2) search 에선 .을 포함한 모든 글자가 동일한 단어가 있는지 확인

search
Time: O(n * w)
Space: O(1)
"""


class WordDictionary:

def __init__(self):
self.root = set()

def addWord(self, word: str) -> None:
self.root.add(word)

def search(self, word: str) -> bool:
for candidate in self.root:
if len(candidate) != len(word):
continue
if all(w == c or w == "." for w, c in zip(word, candidate)):
return True
return False


"""
풀이를 보고 공부했습니다.

Solution: Trie - 달레의 코드
"""


class WordDictionary:

def __init__(self):
self.root = {"$": True}

def addWord(self, word: str) -> None:
node = self.root
for ch in word:
if ch not in node:
node[ch] = {"$": False}
node = node[ch]
node["$"] = True

def search(self, word: str) -> bool:
def dfs(node, idx):
if idx == len(word):
return node["$"]

ch = word[idx]
if ch in node:
return dfs(node[ch], idx + 1)
if ch == ".":
if any(dfs(node[k], idx + 1) for k in node if k != "$"):
return True
return False

return dfs(self.root, 0)


"""
풀이를 보고 공부했습니다.

Solution: Trie with TrieNode - NeetCode
"""


class TrieNode:
def __init__(self):
self.children = {} # a: TrieNode
self.word = False


class WordDictionary:

def __init__(self):
self.root = TrieNode()

def addWord(self, word: str) -> None:
cur = self.root

for c in word:
if c not in cur.children:
cur.children[c] = TrieNode()
cur = cur.children[c]
cur.word = True

def search(self, word: str) -> bool:
def dfs(j, root):
cur = root
for i in range(j, len(word)):
c = word[i]

if c == ".":
for child in cur.children.values():
if dfs(i + 1, child):
return True
return False
else:
if c not in cur.children:
return False
cur = cur.children[c]
return cur.word

return dfs(0, self.root)
49 changes: 49 additions & 0 deletions encode-and-decode-strings/Chaedie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""
Solution:
1) encode: 각 글자의 앞에 글자수와 # 라는 delimiter 를 붙여 stringify 한다.
2) decode: length 를 참고삼아 word를 따내어 result 배열을 만든다.

encode:
Time: O(n) (n: strs 배열의 길이만큼 연산)
Space: O(1)

decode:
Time: O(n) (n: s 의 길이만큼 연산)
Space: O(m) (m: decode 이후 배열의 길이)
"""


class Codec:

def encode(self, strs: List[str]) -> str:
"""Encodes a list of strings to a single string."""
result = ""
for word in strs:
result += str(len(word))
result += "#"
result += word
return result

def decode(self, s: str) -> List[str]:
"""Decodes a single string to a list of strings."""
i = 0
result = []
length = ""
while i < len(s):
# find number
length = ""
while s[i] is not "#":
length += s[i]
i += 1
# find #
i += 1
# find word
result.append(s[i : i + int(length)])
i += int(length)

return result


# Your Codec object will be instantiated and called as such:
# codec = Codec()
# codec.decode(codec.encode(strs))
44 changes: 44 additions & 0 deletions longest-increasing-subsequence/Chaedie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""
Solution: 1) DFS Brute Force -> TLE
Time: O(2^n * nlogn)
Copy link
Contributor

Choose a reason for hiding this comment

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

LIS 알고리즘이 문제는 간단한데, 최적화 알고리즘을 이해하기 많이 어려웠던 기억이 납니다 ㅎㅎ
이건 제가 2기 참여할 당시에 wikipedia에서 LIS 알고리즘을 참고하며 이해하려고 정리한 풀이인데, 도움이 되었으면 좋겠습니다

Copy link
Contributor Author

Choose a reason for hiding this comment

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

wiki 까지 찾아보며 정석대로(?) 공부하는 방법이 있다는걸 처음 알게되었네요. 감사합니다. 이번주차 PR 은 우선 merge 한 뒤에 개인적으로 다시 공부해보겠습니다.

다음주차부터는 모르는 부분에 대해 DIscussion 통해 질문해보도록 하겠습니다. 감사합니다 👍

"""


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

sub = []
max_len = 0

def dfs(i, length):
nonlocal max_len
if i == len(nums):
if sub == sorted(list(set(sub))):
max_len = max(len(sub), max_len)
return

dfs(i + 1, length)
sub.append(nums[i])
dfs(i + 1, length)
sub.pop()

dfs(0, 0)
return max_len


"""
풀이를 보고 적었으며, 완벽히 이해 되지는 않습니다.
Copy link
Contributor

Choose a reason for hiding this comment

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

어떤 부분이 이해가 잘 안되셨나요? 제가 도울 수 있다면 도와드리겠습니다
+이런 부분들을 Discussion에 올려주시면 좋을 것 같아요 ㅎㅎ

Time: O(n^2)
Space: O(n)
"""


class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
LIS = [1] * len(nums)

for i in range(len(nums) - 1, -1, -1):
for j in range(i + 1, len(nums)):
if nums[i] < nums[j]:
LIS[i] = max(LIS[i], 1 + LIS[j])
return max(LIS)
46 changes: 46 additions & 0 deletions spiral-matrix/Chaedie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""
Solution:
1) 좌우 상하의 경계를 좁혀가며 순회한다.
2) 탈출 조건으로 result 의 사이즈가 matrix 의 원소 갯수가 같아지는지 확인한다.
(탈출 조건을 좌우 상하 경계가 넘어가는 시험을 기준으로 삼은 솔루션을 봤지만, 정확히 이해는 되지 않아 사이즈 비교로 진행했습니다.)
Copy link
Contributor

Choose a reason for hiding this comment

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

지금 풀이에서도 상하좌우 경계를 관리하고 계신대요? 어떤 부분이 이해가 잘 안 되셨을까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if len(result) == len(matrix[0]) * len(matrix):
                break

저의 경우 이렇게 break 로 탈출하는 지점을 4개 반복으로 만들었는데요, 달레님 블로그글만 보더라도

# 상단 인덱스가 하단 인덱스보다 커지면 순회 중단
if top > bottom:
    break

  # 우측 인덱스가 좌측 인덱스보다 작아지면 순회 중단
  if left > right:
      break

이렇게 인덱스를 통해 탈출조건을 지정했더라구요, 이 부분이 어렴풋이 이해는 되지만, 명확하게 이해가 되지 않다보니 제가 짠다면 저는 또 다시 4번의 탈출문을 넣을것 같습니다.

Time: O(m * n)
Space: O(1)
"""


class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
result = []
left, right = 0, len(matrix[0])
top, bottom = 0, len(matrix)

while left < right and top < bottom:
for i in range(left, right):
result.append(matrix[top][i])
top += 1

if len(result) == len(matrix[0]) * len(matrix):
break

for i in range(top, bottom):
result.append(matrix[i][right - 1])
right -= 1

if len(result) == len(matrix[0]) * len(matrix):
break

for i in range(right - 1, left - 1, -1):
result.append(matrix[bottom - 1][i])
bottom -= 1

if len(result) == len(matrix[0]) * len(matrix):
break

for i in range(bottom - 1, top - 1, -1):
result.append(matrix[i][left])
left += 1

if len(result) == len(matrix[0]) * len(matrix):
break

return result
67 changes: 67 additions & 0 deletions valid-parentheses/Chaedie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""
Solution:
1) s 를 순회하면서 여는 괄호면 stack 에 push 한다.
2) 닫는 괄호일 경우 각 case 별로 stack 의 최상단이 알맞는 여는 괄호이면 stack 을 pop 하고 아니면 False 를 return 한다.
Time: O(n)
Space: O(n)
"""


class Solution:
def isValid(self, s: str) -> bool:
stack = []
left = ["(", "{", "["]
for char in s:
if char in left:
stack.append(char)
continue

if not stack:
return False

if char == ")":
if stack[-1] == "(":
stack.pop()
else:
return False
if char == "}":
if stack[-1] == "{":
stack.pop()
else:
return False
if char == "]":
if stack[-1] == "[":
stack.pop()
else:
return False

return not stack


"""
Solution:
1) stack과 hash map을 사용한다.
2) s를 순회하면서 여는 괄호일 경우 stack 에 push
3) 닫는 괄호일 경우 stack 이 비지 않으면서 최상단 요소가 알맞은 여는 괄호이면 stack pop, 아닐 경우 return False

Time: O(n)
Space: O(n)
"""


class Solution:
def isValid(self, s: str) -> bool:
opening = "({["
closing = ")}]"
closeToOpen = dict(zip(closing, opening))

stack = []
for char in s:
if char in opening:
stack.append(char)
else:
if stack and stack[-1] == closeToOpen[char]:
stack.pop()
else:
return False
return not stack
Loading