-
Notifications
You must be signed in to change notification settings - Fork 126
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #507 from lymchgmk/week8
[EGON] Week8 Solutions
- Loading branch information
Showing
5 changed files
with
270 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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 Optional, TypeVar | ||
from unittest import TestCase, main | ||
|
||
|
||
# Definition for a Node. | ||
class Node: | ||
def __init__(self, val = 0, neighbors = None): | ||
self.val = val | ||
self.neighbors = neighbors if neighbors is not None else [] | ||
|
||
|
||
class Solution: | ||
def cloneGraph(self, node: Optional[Node]) -> Optional[Node]: | ||
return self.solve(node) | ||
|
||
""" | ||
Runtime: 42 ms (Beats 45.48%) | ||
Time Complexity: O(n) | ||
Memory: 17.04 (Beats 8.15%) | ||
Space Complexity: O(n), upper bound | ||
""" | ||
def solve(self, node: Optional[Node]) -> Optional[Node]: | ||
clone_dict = {} | ||
stack = [node] | ||
visited = set() | ||
while stack: | ||
curr_node = stack.pop() | ||
visited.add(curr_node.val) | ||
if curr_node.val not in clone_dict: | ||
clone_dict[curr_node.val] = Node(val=curr_node.val) | ||
|
||
for neighbor in curr_node.neighbors: | ||
if neighbor.val not in clone_dict: | ||
clone_dict[neighbor.val] = Node(val=neighbor.val) | ||
|
||
if neighbor.val not in visited: | ||
clone_dict[curr_node.val].neighbors.append(clone_dict[neighbor.val]) | ||
clone_dict[neighbor.val].neighbors.append(clone_dict[curr_node.val]) | ||
stack.append(neighbor) | ||
|
||
return clone_dict[node.val] | ||
|
||
|
||
class _LeetCodeTestCases(TestCase): | ||
def test_1(self): | ||
node_dict = {1: Node(1), 2: Node(2), 3: Node(3), 4: Node(4)} | ||
node_dict[1].neighbors = [node_dict[2], node_dict[4]] | ||
node_dict[2].neighbors = [node_dict[1], node_dict[3]] | ||
node_dict[3].neighbors = [node_dict[2], node_dict[4]] | ||
node_dict[4].neighbors = [node_dict[1], node_dict[3]] | ||
|
||
Solution.cloneGraph(Solution(), node_dict[1]) | ||
self.assertTrue("RUN") | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains 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,44 @@ | ||
from unittest import TestCase, main | ||
|
||
|
||
class Solution: | ||
def longestCommonSubsequence(self, text1: str, text2: str) -> int: | ||
return self.solve_dp(text1, text2) | ||
|
||
""" | ||
Runtime: 441 ms (Beats 85.60%) | ||
Time Complexity: O(m * n) | ||
- text1, text2์ ๊ธธ์ด๋ฅผ ๊ฐ๊ฐ m, n์ด๋ผ ํ๋ฉด ์ด์ค for๋ฌธ ์กฐํ์ O(m * n) | ||
- i. dp ๋ฐฐ์ด ๊ฐ ๊ฐฑ์ ์์ ๊ธฐ์กด๊ฐ +1์ O(1) | ||
- ii. dp ๋ฐฐ์ด ๊ฐ ๊ฐฑ์ ์์ 2๊ฐ ํญ์ ๋ํ max ์ฐ์ฐ์ O(2), upper bound | ||
> O(m * n) * O(2) ~= O(m * n) | ||
Memory: 41.81 (Beats 55.93%) | ||
Space Complexity: O(m * n) | ||
> row์ ๊ธธ์ด๊ฐ n์ด๊ฐ col์ ๊ธธ์ด๊ฐ m์ธ 2์ฐจ์ ๋ฐฐ์ด dp ์ฌ์ฉ์ O(m * n) | ||
""" | ||
def solve_dp(self, text1: str, text2: str) -> int: | ||
dp = [[0] * (len(text2) + 1) for _ in range(len(text1) + 1)] | ||
for idx1 in range(len(text1)): | ||
for idx2 in range(len(text2)): | ||
if text1[idx1] == text2[idx2]: | ||
dp[idx1 + 1][idx2 + 1] = dp[idx1][idx2] + 1 | ||
else: | ||
dp[idx1 + 1][idx2 + 1] = max(dp[idx1 + 1][idx2], dp[idx1][idx2 + 1]) | ||
|
||
return dp[-1][-1] | ||
|
||
|
||
class _LeetCodeTestCases(TestCase): | ||
def test_1(self): | ||
text1 = "abcde" | ||
text2 = "ace" | ||
output = 3 | ||
self.assertEqual( | ||
Solution().longestCommonSubsequence(text1, text2), | ||
output | ||
) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains 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,48 @@ | ||
from unittest import TestCase, main | ||
from collections import defaultdict | ||
|
||
|
||
class Solution: | ||
def characterReplacement(self, s: str, k: int) -> int: | ||
return self.solve_sliding_window(s, k) | ||
|
||
""" | ||
Runtime: 63 ms (Beats 98.40%) | ||
Time Complexity: O(n) | ||
- s์ ๋ํด ์กฐํํ๋๋ฐ O(n) | ||
- dict์ธ counter๋ฅผ ์ฌ์ฉํด์ ํน์ ๋ฌธ์์ ๋น๋์ ์ฒดํฌ, ๋ถ๊ธฐ์ฒ๋ฆฌ, most_common_char ๊ฐฑ์ ์ O(1) | ||
- ํ์ฌ ์ต์ฅ ๊ธธ์ด ๊ณ์ฐ์ int ๊ณ์ฐ๋ง ์ฌ์ฉํ๋ฏ๋ก O(1) | ||
> O(n) * O(1) ~= O(n) | ||
Memory: 16.54 (Beats 76.70%) | ||
Space Complexity: O(n), upper bound | ||
- left, right ๊ฐ์ int ์ธ๋ฑ์ค ๋ณ์ ํ ๋น์ O(1) | ||
- most_common_char๊ฐ์ str ๋ณ์ ํ ๋น์ O(1) | ||
- dict์ธ counter์ ์ต๋ ํฌ๊ธฐ๋ s์ ๋ชจ๋ ๋ฌธ์๊ฐ ๋ค๋ฅด๊ณ k์ ํฌ๊ธฐ๊ฐ len(s)์ธ ๊ฒฝ์ฐ์ด๋ฏ๋ก O(n), upper bound | ||
> O(n), upper bound | ||
""" | ||
def solve_sliding_window(self, s: str, k: int) -> int: | ||
left = right = 0 | ||
counter, most_common_char = defaultdict(int), "" | ||
for right in range(len(s)): | ||
counter[s[right]] += 1 | ||
if counter[most_common_char] < counter[s[right]]: | ||
most_common_char = s[right] | ||
|
||
if (right - left + 1) - counter[most_common_char] > k: | ||
counter[s[left]] -= 1 | ||
left += 1 | ||
|
||
return right - left + 1 | ||
|
||
|
||
class _LeetCodeTestCases(TestCase): | ||
def test_1(self): | ||
s = "AABBCC" | ||
k = 2 | ||
output = 4 | ||
self.assertEqual(Solution.characterReplacement(Solution(), s, k), output) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains 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,79 @@ | ||
from typing import Optional | ||
from unittest import TestCase, main | ||
|
||
|
||
class ListNode: | ||
def __init__(self, val=0, next=None): | ||
self.val = val | ||
self.next = next | ||
|
||
|
||
class Solution: | ||
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]: | ||
return self.solve(list1, list2) | ||
|
||
""" | ||
Runtime: 36 ms (Beats 71.91%) | ||
Time Complexity: O(m + n) | ||
> list1์ ๊ธธ์ด๋ฅผ m, list2์ ๊ธธ์ด๋ฅผ n์ด๋ผ ํ ๋, list1๊ณผ list2 ๋ชจ๋ ๋๊น์ง ์กฐํํ๋ฏ๋ก O(n + m) | ||
Memory: 16.62 (Beats 37.59%) | ||
Space Complexity: O(m + n) | ||
> result์ ๊ธธ์ด๋ list1์ ๊ธธ์ด์ list2์ ๊ธธ์ด์ ํฉ๊ณผ ๊ฐ์ผ๋ฏ๋ก O(m + n) | ||
""" | ||
def solve(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]: | ||
result = ListNode() | ||
node = result | ||
while list1 or list2: | ||
if list1 and list2: | ||
if list1.val < list2.val: | ||
node.next = list1 | ||
node = node.next | ||
list1 = list1.next | ||
else: | ||
node.next = list2 | ||
node = node.next | ||
list2 = list2.next | ||
|
||
elif list1 and not list2: | ||
node.next = list1 | ||
node = node.next | ||
list1 = list1.next | ||
|
||
elif not list1 and list2: | ||
node.next = list2 | ||
node = node.next | ||
list2 = list2.next | ||
|
||
else: | ||
break | ||
|
||
return result.next | ||
|
||
|
||
class _LeetCodeTestCases(TestCase): | ||
def test_1(self): | ||
list1 = ListNode( | ||
val=1, | ||
next=ListNode( | ||
val=2, | ||
next=ListNode( | ||
val=4 | ||
) | ||
) | ||
) | ||
list2 = ListNode( | ||
val=1, | ||
next=ListNode( | ||
val=3, | ||
next=ListNode( | ||
val=4 | ||
) | ||
) | ||
) | ||
output = [1,1,2,3,4,4] | ||
self.assertEqual(Solution.mergeTwoLists(Solution(), list1, list2), output) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains 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,41 @@ | ||
from unittest import TestCase, main | ||
|
||
|
||
class Solution: | ||
def getSum(self, a: int, b: int) -> int: | ||
return self.solve_bit(a, b) | ||
|
||
""" | ||
Runtime: 26 ms (Beats 94.94%) | ||
Time Complexity: O(log max(a, b)) ~= O(1) | ||
- a์ b๋ฅผ and ์ฐ์ฐ ํ ์ผ์ชฝ์ผ๋ก shiftํ ๊ฐ์ b์ ํ ๋นํ๋๋ฐ ๋ชจ๋ ๋นํธ์ฐ์ฐ์ด๋ฏ๋ก O(1) | ||
- b์ ๊ฐ์ด ์ผ์ชฝ shift์ ์ํด ๊ฐ์ํ๋ฏ๋ก log(b) | ||
- ๋จ b์ ๊ฐ์ a & b์ ์ํด ๊ฒฐ์ ๋๋ฏ๋ก log max(a, b) | ||
- ์ ์ ์กฐ๊ฑด์์ a, b๋ ๋ชจ๋ ์ ๋๊ฐ 1000 ์ดํ์ ๊ฐ์ด๋ฏ๋ก, ์ต๋ 10ํ์ shift ์ฐ์ฐ๋ง ๋ฐ์ํ๋ฏ๋ก, O(10) ~= O(1) | ||
> O(log max(a, b)) < O(10) ~= O(1) | ||
Memory: 16.52 (Beats 18.98%) | ||
Space Complexity: O(1) | ||
> input์ ๋ฌด๊ดํ๊ฒ ์ ์ํ ๋ณ์๋ค๋ง ์ฌ์ฉํ๋ฏ๋ก O(1) | ||
""" | ||
def solve_bit(self, a: int, b: int) -> int: | ||
COMPLEMENT_MASK = 0xFFF | ||
|
||
while b != 0: | ||
carry = a & b | ||
a = (a ^ b) & COMPLEMENT_MASK | ||
b = (carry << 1) & COMPLEMENT_MASK | ||
|
||
return a if a <= 0x7FF else ~(a ^ COMPLEMENT_MASK) | ||
|
||
|
||
class _LeetCodeTestCases(TestCase): | ||
def test_1(self): | ||
a = -1 | ||
b = 1 | ||
output = 0 | ||
self.assertEqual(Solution().getSum(a, b), output) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |