-
-
Notifications
You must be signed in to change notification settings - Fork 195
[EGON] Week 6 Solutions #467
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
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from typing import List | ||
from unittest import TestCase, main | ||
|
||
|
||
class Solution: | ||
def maxArea(self, height: List[int]) -> int: | ||
return self.solveWithTwoPointer(height) | ||
|
||
""" | ||
Runtime: 527 ms (Beats 47.12%) | ||
Time Complexity: O(n) | ||
- 투 포인터의 총합 조회 범위가 height의 길이와 같으므로 O(n) | ||
- area 갱신을 위한 계산에서 항이 2개인 max와 항이 2개인 min 중첩에 O(2) * O(2) | ||
> O(n) * O(4) ~= O(n) | ||
|
||
Memory: 29.61 MB (Beats 38.93%) | ||
Space Complexity: O(1) | ||
> 정수형 변수들만 사용했으므로 O(1) | ||
""" | ||
def solveWithTwoPointer(self, height: List[int]) -> int: | ||
left, right = 0, len(height) - 1 | ||
area = 0 | ||
while left < right: | ||
area = max(area, (right - left) * min(height[right], height[left])) | ||
|
||
if height[left] <= height[right]: | ||
left += 1 | ||
else: | ||
right -= 1 | ||
|
||
return area | ||
|
||
|
||
class _LeetCodeTestCases(TestCase): | ||
def test_1(self): | ||
height = [1, 8, 6, 2, 5, 4, 8, 3, 7] | ||
output = 49 | ||
self.assertEqual(Solution.maxArea(Solution(), height), output) | ||
|
||
def test_2(self): | ||
height = [1, 1] | ||
output = 1 | ||
self.assertEqual(Solution.maxArea(Solution(), height), output) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
from unittest import TestCase, main | ||
|
||
|
||
class Node: | ||
|
||
def __init__(self, key): | ||
self.key = key | ||
self.isWordEnd = False | ||
self.children = {} | ||
|
||
|
||
class Trie: | ||
WILD_CARD = '.' | ||
|
||
def __init__(self): | ||
self.root = Node(None) | ||
|
||
def insert(self, word: str) -> None: | ||
curr_node = self.root | ||
for char in word: | ||
if char not in curr_node.children: | ||
curr_node.children[char] = Node(char) | ||
|
||
curr_node = curr_node.children[char] | ||
curr_node.isWordEnd = True | ||
|
||
def search(self, node: Node, word: str, idx: int) -> bool: | ||
if idx == len(word): | ||
return node.isWordEnd | ||
|
||
for idx in range(idx, len(word)): | ||
if word[idx] == self.WILD_CARD: | ||
for child in node.children.values(): | ||
if self.search(child, word, idx + 1) is True: | ||
return True | ||
else: | ||
return False | ||
|
||
if word[idx] in node.children: | ||
return self.search(node.children[word[idx]], word, idx + 1) | ||
else: | ||
return False | ||
|
||
|
||
""" | ||
Runtime: 1810 ms (Beats 22.46%) | ||
Time Complexity: | ||
> addWord: word의 길이만큼 순회하므로 O(L) | ||
> search: | ||
- word의 평균 길이를 W이라하면, | ||
- '.'가 포함되어 있지 않는 경우 O(W), early return 가능하므로 upper bound | ||
- '.'가 포함되어 있는 경우, 해당 노드의 child만큼 재귀, trie의 평균 자식 수를 C라 하면 O(W) * O(C), early return 가능하므로 upper bound | ||
- trie의 평균 자식 수는 addWord의 실행횟수 C'에 선형적으로 비레(겹치는 char가 없는 경우 upper bound) | ||
> O(W) * O(C) ~= O(W) * O(C') ~= O(W * C'), upper bound | ||
|
||
Memory: 66.78 MB (Beats 12.26%) | ||
Space Complexity: O(1) | ||
> addWord: | ||
- 삽입한 word의 평균 길이 L만큼 Node가 생성 및 Trie에 추가, O(L) | ||
- addWord의 실행횟수 C'에 비례, O(C') | ||
> O(L) * O(C') ~= O(L * C') | ||
> search: | ||
> 만들어진 Trie와 패러미터 word, 정수 변수 idx를 사용하므로 O(1) | ||
|
||
""" | ||
class WordDictionary: | ||
|
||
def __init__(self): | ||
self.trie = Trie() | ||
|
||
def addWord(self, word: str) -> None: | ||
self.trie.insert(word) | ||
|
||
def search(self, word: str) -> bool: | ||
return self.trie.search(self.trie.root, word, 0) | ||
|
||
|
||
class _LeetCodeTestCases(TestCase): | ||
def test_1(self): | ||
wordDictionary = WordDictionary() | ||
wordDictionary.addWord("at") | ||
self.assertEqual(wordDictionary.search(".at"), False) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
from typing import List | ||
from unittest import TestCase, main | ||
|
||
|
||
class Solution: | ||
def lengthOfLIS(self, nums: List[int]) -> int: | ||
return self.solve_with_Memo_BS(nums) | ||
|
||
""" | ||
Runtime: 68 ms (Beats 86.42%) | ||
Time Complexity: O(n) | ||
- nums 배열 조회에 O(n) | ||
- 최악의 경우 num의 모든 원소에 대해 bisect_left 실행가능, O(log n) upper bound | ||
> O(n) * O(log n) ~= O(n * log n) | ||
|
||
Memory: 16.92 MB (Beats 29.49%) | ||
Space Complexity: O(n) | ||
> 최대 크기가 n인 lis 배열 사용에 O(n) | ||
""" | ||
def solve_with_Memo_BS(self, nums: List[int]) -> int: | ||
|
||
def bisect_left(lis: List[int], target: int): | ||
lo, hi = 0, len(lis) | ||
while lo < hi: | ||
mid = lo + (hi - lo) // 2 | ||
if lis[mid] < target: | ||
lo = mid + 1 | ||
else: | ||
hi = mid | ||
|
||
return lo | ||
|
||
lis = [] | ||
for num in nums: | ||
if not lis: | ||
lis.append(num) | ||
continue | ||
|
||
if lis[-1] < num: | ||
lis.append(num) | ||
else: | ||
lis[bisect_left(lis, num)] = num | ||
|
||
return len(lis) | ||
|
||
|
||
class _LeetCodeTestCases(TestCase): | ||
def test_1(self): | ||
prices = [10,9,2,5,3,7,101,18] | ||
output = 4 | ||
self.assertEqual(Solution.lengthOfLIS(Solution(), prices), output) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
from typing import List | ||
from unittest import TestCase, main | ||
|
||
|
||
class Solution: | ||
def spiralOrder(self, matrix: List[List[int]]) -> List[int]: | ||
return self.solve(matrix) | ||
|
||
""" | ||
Runtime: 37 ms (Beats 44.53%) | ||
Time Complexity: O(MAX_R * MAX_C) | ||
|
||
Memory: 16.56 MB (Beats 43.42%) | ||
Space Complexity: O(1) | ||
- result를 제외하고 matrix의 값을 변경해서 visited 분기 | ||
""" | ||
def solve(self, matrix: List[List[int]]) -> List[int]: | ||
MAX_R, MAX_C = len(matrix), len(matrix[0]) | ||
DIRS = ((0, 1), (1, 0), (0, -1), (-1, 0)) | ||
result = [] | ||
r, c, dir_idx = 0, -1, 0 | ||
for _ in range(MAX_R * MAX_C): | ||
r += DIRS[dir_idx][0] | ||
c += DIRS[dir_idx][1] | ||
|
||
if 0 <= r < MAX_R and 0 <= c < MAX_C and matrix[r][c] is not None: | ||
result.append(matrix[r][c]) | ||
matrix[r][c] = None | ||
else: | ||
r -= DIRS[dir_idx][0] | ||
c -= DIRS[dir_idx][1] | ||
dir_idx = (dir_idx + 1) % len(DIRS) | ||
r += DIRS[dir_idx][0] | ||
c += DIRS[dir_idx][1] | ||
result.append(matrix[r][c]) | ||
matrix[r][c] = None | ||
|
||
return result | ||
|
||
|
||
class _LeetCodeTestCases(TestCase): | ||
def test_1(self): | ||
matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]] | ||
output = [1,2,3,4,8,12,11,10,9,5,6,7] | ||
self.assertEqual(Solution.spiralOrder(Solution(), matrix), output) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
from typing import List | ||
from unittest import TestCase, main | ||
|
||
|
||
class Solution: | ||
def isValid(self, s: str) -> bool: | ||
return self.solveWithStack(s) | ||
|
||
""" | ||
Runtime: 34 ms (Beats 66.54%) | ||
Time Complexity: O(n) | ||
> 문자열 s의 길이 L만큼 조회하므로 O(n), early return이 있으므로 upper bound | ||
|
||
Memory: 16.59 MB (Beats 50.97%) | ||
Space Complexity: O(n) | ||
- close_p_dict의 크기는 상수로 처리 | ||
> 최대 길이가 L인 배열 stack을 사용했으므로 O(n) | ||
""" | ||
def solveWithStack(self, s: str) -> bool: | ||
close_p_dict = {')': '(', '}': '{', ']': '['} | ||
stack = [] | ||
for curr_p in s: | ||
if not stack or curr_p not in close_p_dict: | ||
stack.append(curr_p) | ||
continue | ||
|
||
if close_p_dict[curr_p] != stack[-1]: | ||
return False | ||
else: | ||
stack.pop() | ||
|
||
return not stack | ||
|
||
|
||
class _LeetCodeTestCases(TestCase): | ||
def test_1(self): | ||
s = "()" | ||
output = True | ||
self.assertEqual(Solution.isValid(Solution(), s), output) | ||
|
||
def test_2(self): | ||
s = "()[]{}" | ||
output = True | ||
self.assertEqual(Solution.isValid(Solution(), s), output) | ||
|
||
def test_3(self): | ||
s = "(]" | ||
output = False | ||
self.assertEqual(Solution.isValid(Solution(), s), output) | ||
|
||
def test_4(self): | ||
s = "([])" | ||
output = True | ||
self.assertEqual(Solution.isValid(Solution(), s), output) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.