-
-
Notifications
You must be signed in to change notification settings - Fork 361
[dolphinflow86] WEEK 02 Solutions #2677
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
Changes from all commits
7f80073
d5a06a5
4ddaf98
ae0679b
b85bcd8
ac7e3f3
966119b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Contributor
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. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
피드백: 정렬 후 중복 제거를 위해 i 인덱스의 이전 값과 비교하고, 내부에서 해시맵으로 보조 탐색을 수행합니다. 개선 제안: 현재 구현이 충분히 효율적이지만, 중복 제거를 더 엄격하게 관리하거나 두 포인터로 구현하면 상수 계수 개선이 가능합니다. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # 1) Fix one element first, and then treat others as two-sum problem. Use set to get rid of duplicate combination. | ||
| # TC: O(N^2) where N is the length of nums. | ||
| # SC: O(N) where N is the length of nums. | ||
| class Solution: | ||
| def threeSum(self, nums: list[int]) -> list[list[int]]: | ||
| answer: Set[tuple[int,int,int]] = set() | ||
| n = len(nums) | ||
| nums.sort() | ||
|
|
||
| for i in range(n-2): | ||
| if i > 0 and nums[i] == nums[i-1]: continue | ||
|
|
||
| target = -nums[i] | ||
| nums_map: Dict[int, int] = {} | ||
| for j in range(i + 1, n): | ||
| comp = target - nums[j] | ||
| if comp in nums_map: | ||
| answer.add((nums[i], comp, nums[j])) | ||
| nums_map[nums[j]] = j | ||
|
|
||
| return [list(triplet) for triplet in answer] |
|
Contributor
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. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
피드백: 상향식 동적 프로그래밍을 재귀로 구현해 중복을 제거했습니다. 메모이제이션으로 불필요한 재호출 감소. 개선 제안: 루틴을 반복문으로 변환하면 호출 스택 사용을 피하고 상수 공간으로 개선할 수 있습니다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| # 1) Recursion with memoization. | ||
| # TC: O(N) where N is the given natural number. | ||
| # SC: O(N) where N is the given natural number. | ||
| class Solution: | ||
|
Contributor
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. 바텀업 + 메모라이제이션을 사용하셨네요! 각 전진 케이스에 대해서 이미 계산되어있으면 해당 값을 사용하고, 아니라면 계산해서 저장하는 방식으로 이해하였습니다. 저는 탑다운 + 메모라이제이션으로 문제를 접근했는데 이런 방식으로 생각을 해볼 수 있겠네요 ㅎㅎ
Contributor
Author
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. @JeonJe 이 문제는 각 스탭마다 행할 수 있는 행동이 1칸 아니면 2칸의 점프라고 생각했고 피보나치나 house robber 문제에서 풀었던 풀이를 적용해볼 수 있겠다라는 생각이 들어서 재귀로 접근했습니다. 실행 흐름은 1층부터 n층까지 재귀적으로 올라가되, n층에서 베이스케이스에 걸려 내려오면서 memo를 채우는식으로 구현하였고, 저도 헷갈려서 결정트리 그려보면서 다시 리마인드 했네요 :) |
||
| def climb_rec(self, n: int, step: int, memo: Dict[int, int]): | ||
| if step > n: return 0 | ||
| if step in memo: return memo[step] | ||
| if step == n: return 1 | ||
|
|
||
| first_way = self.climb_rec(n, step + 1, memo) | ||
| second_way = self.climb_rec(n, step + 2, memo) | ||
| memo[step] = first_way + second_way | ||
| return memo[step] | ||
|
|
||
|
|
||
| def climbStairs(self, n: int) -> int: | ||
| if n == 1: return 1 | ||
|
|
||
| memo = {} | ||
| return self.climb_rec(n, 1, memo) + self.climb_rec(n, 2, memo) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| # 1) Without using division operator and need to meet linear time complexity, | ||
| # calculate left accumulated product and calculate right accumulated product except iself and then | ||
| # product of left and right to get the result. | ||
| # TC: O(N) where N is the length of nums | ||
| # SC: O(N) where N is the length of nums | ||
| class Solution: | ||
| def productExceptSelf(self, nums: List[int]) -> List[int]: | ||
| n = len(nums) | ||
| answer = [1] * n | ||
| acc = 1 | ||
| for i in range(1, n): | ||
| acc *= nums[i-1] | ||
| answer[i] = acc | ||
|
|
||
| acc = 1 | ||
| for i in range(n-2, -1, -1): | ||
| acc *= nums[i+1] | ||
| answer[i] *= acc | ||
|
|
||
| return answer |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| # 1) Sort input strings and check if those are the same. | ||
| # TC: O(NlogN) where N is the size of string s and t due to sorting | ||
| # SC: O(N) where N is the length of string s and t to store sorted list. | ||
| class Solution: | ||
|
Contributor
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. 안녕하세요! 이번에 코드리뷰를 맡게 된 이전제입니다. 잘부탁드립니다. solve 코드 너무 깔끔하게 잘 작성하셨네요!! 시간복잡도를 더 낮춰야한다는 제약조건이 있다면, 정렬이 아닌 어떤 다른 방식으로 문제 풀이 접근하실 지 궁금합니다!
Contributor
Author
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. @JeonJe 안녕하세요 전제님 :) 저도 잘 부탁드립니다. 이 문제는 시간복잡도를 더 낮춘다면 아래의 2번째 방법으로 푼 해시맵 사용하는 방법으로 접근하여 풀 것 같습니다. 다만 2번 솔루션에서도 s와 t가 영문 소문자 제한이 있어서 해시맵 대신에 26크기의 고정배열로 변경해서 푸는 것으로 조금 더 최적화를 할 수 있을 것 같아요. |
||
| def isAnagram(self, s: str, t: str) -> bool: | ||
| return sorted(s) == sorted(t) | ||
|
|
||
| # 2) Using dict to store count of the first string and decrease back to see if there's negative count. | ||
| # TC: O(N + M) where N is the length of s and M is the length of t. | ||
| # SC: O(N + M) where N is the length of s and M is the length of t. | ||
| class Solution: | ||
| def isAnagram(self, s: str, t: str) -> bool: | ||
| if len(s) != len(t): return False | ||
|
|
||
| char_map: Dict[str, int] = {} | ||
| for ch in s: | ||
| char_map[ch] = char_map.get(ch, 0) + 1 | ||
|
|
||
| for ch in t: | ||
| if ch not in char_map or char_map[ch] == 0: | ||
| return False | ||
|
|
||
| char_map[ch] -= 1 | ||
|
|
||
| return True | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| # 1) Validate the BST using min and max values for each node. | ||
| # TC: O(N) where N is the number of nodes in the BST | ||
| # SC: O(H) where H is the height of the BST | ||
|
|
||
| # Definition for a binary tree node. | ||
| # class TreeNode: | ||
| # def __init__(self, val=0, left=None, right=None): | ||
| # self.val = val | ||
| # self.left = left | ||
| # self.right = right | ||
| class Solution: | ||
| def solve(self, node: Optional[TreeNode], min: int, max: int) -> bool: | ||
| if node == None: return True | ||
|
|
||
| if node.val <= min or node.val >= max: return False | ||
|
|
||
| left = self.solve(node.left, min, node.val) | ||
| right = self.solve(node.right, node.val, max) | ||
| return left and right | ||
|
|
||
| def isValidBST(self, root: Optional[TreeNode]) -> bool: | ||
| return self.solve(root, float('-inf'), float('inf')) |
Uh oh!
There was an error while loading. Please reload this page.
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.
오 이러면 왼쪽 포인터를 하나 두고
오른쪽 부분만 부분문제처럼 Two sum 문제로 푸신거리고 보면 될까요?
이런 방법도 있다니 너무 신기하네요! 고생하셨습니다!
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.
@alphaorderly 리뷰해주셔서 감사합니다. 네 해당 방식이 맞아요.
하지만 구현해놓고 보니 투포인터 방식이 좀 더 깔끔한 것 같긴 하더라구요 :)