-
-
Notifications
You must be signed in to change notification settings - Fork 195
[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
[Chaedie] Week 6 #897
Changes from all commits
77e9a35
41046a9
d60f811
23cdf0f
721c972
7270572
9b3dbce
8b31585
6eccf0f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 |
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) |
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)) |
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) | ||
""" | ||
|
||
|
||
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 | ||
|
||
|
||
""" | ||
풀이를 보고 적었으며, 완벽히 이해 되지는 않습니다. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 어떤 부분이 이해가 잘 안되셨나요? 제가 도울 수 있다면 도와드리겠습니다 |
||
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) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
""" | ||
Solution: | ||
1) 좌우 상하의 경계를 좁혀가며 순회한다. | ||
2) 탈출 조건으로 result 의 사이즈가 matrix 의 원소 갯수가 같아지는지 확인한다. | ||
(탈출 조건을 좌우 상하 경계가 넘어가는 시험을 기준으로 삼은 솔루션을 봤지만, 정확히 이해는 되지 않아 사이즈 비교로 진행했습니다.) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 지금 풀이에서도 상하좌우 경계를 관리하고 계신대요? 어떤 부분이 이해가 잘 안 되셨을까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LIS 알고리즘이 문제는 간단한데, 최적화 알고리즘을 이해하기 많이 어려웠던 기억이 납니다 ㅎㅎ
이건 제가 2기 참여할 당시에 wikipedia에서 LIS 알고리즘을 참고하며 이해하려고 정리한 풀이인데, 도움이 되었으면 좋겠습니다
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wiki 까지 찾아보며 정석대로(?) 공부하는 방법이 있다는걸 처음 알게되었네요. 감사합니다. 이번주차 PR 은 우선 merge 한 뒤에 개인적으로 다시 공부해보겠습니다.
다음주차부터는 모르는 부분에 대해 DIscussion 통해 질문해보도록 하겠습니다. 감사합니다 👍