-
-
Notifications
You must be signed in to change notification settings - Fork 245
[KwonNayeon] Week 11 #1030
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
[KwonNayeon] Week 11 #1030
Changes from 6 commits
51f119d
046ac88
dcfb736
89e9adb
5f8b4bd
5a411b0
b49ce60
150d1c3
1f61b43
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,46 @@ | ||
""" | ||
Valid Tree의 조건: | ||
1. 모든 노드가 연결되어 있어야 함 | ||
2. 사이클이 없어야 함 | ||
3. edge의 개수는 n-1개 | ||
|
||
Time Complexity: O(V + E) | ||
- V: 노드의 개수 | ||
- E: edge의 개수 | ||
|
||
Space Complexity: O(V) | ||
- 노드 방문 여부를 저장하는 visited set 사용 | ||
|
||
풀이방법: | ||
1. 기본 조건 체크: edge의 개수는 n-1개 | ||
2. 각 노드별로 연결된 노드들의 정보를 저장 | ||
- 무방향 그래프이므로 양쪽 모두 저장 | ||
3. DFS로 노드 탐색 | ||
- 0번 노드부터 시작해서 연결된 모든 노드를 방문 | ||
- 이미 방문한 노드는 재방문하지 않음 | ||
4. 모든 노드 방문 확인 | ||
- visited의 크기가 n과 같다면 모든 노드가 연결된 것 -> valid tree | ||
""" | ||
def validTree(n, edges): | ||
if len(edges) != n - 1: | ||
return False | ||
|
||
adj = [[] for _ in range(n)] | ||
for a, b in edges: | ||
adj[a].append(b) | ||
adj[b].append(a) | ||
|
||
visited = set() | ||
|
||
def dfs(node): | ||
if node in visited: | ||
return | ||
|
||
visited.add(node) | ||
|
||
for next_node in adj[node]: | ||
dfs(next_node) | ||
|
||
dfs(0) | ||
return len(visited) == n | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
""" | ||
Constraints: | ||
- The number of nodes in the tree is in the range [0, 10^4]. | ||
- -100 <= Node.val <= 100 | ||
|
||
Time Complexity: O(N) | ||
- N은 트리의 노드 수 | ||
- 모든 노드를 한 번씩 방문하기 때문 | ||
|
||
Space Complexity: O(H) | ||
- H는 트리의 높이 | ||
- 재귀 호출로 인한 호출 스택의 최대 깊이가 트리의 높이와 같음 | ||
|
||
풀이방법: | ||
1. Base case: root가 None인 경우 0을 반환 | ||
2. 재귀를 활용하여 왼쪽과 오른쪽 서브트리 깊이를 각각 계산 | ||
3. 두 서브트리의 깊이 중 최대값에 1을 더해서 반환 (현재 노드의 깊이를 포함) | ||
""" | ||
# 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 | ||
|
||
# Solution 1: 재귀 | ||
class Solution: | ||
def maxDepth(self, root: Optional[TreeNode]) -> int: | ||
if root is None: | ||
return 0 | ||
|
||
left_depth = self.maxDepth(root.left) | ||
right_depth = self.maxDepth(root.right) | ||
|
||
return max(left_depth, right_depth) + 1 | ||
|
||
# Solution 2: 반복문 | ||
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. @gwbaik9717 님 안녕하세요! �코드 꼼꼼히 보고 리뷰 남겨주셔서 감사합니다 👍😊 |
||
class Solution: | ||
def maxDepth(self, root: Optional[TreeNode]) -> int: | ||
if root is None: | ||
return 0 | ||
|
||
stack = [(root, 1)] | ||
max_depth = 0 | ||
|
||
while stack: | ||
current, depth = stack.pop() | ||
|
||
max_depth = max(max_depth, depth) | ||
|
||
if current.left: | ||
stack.append((current.left, depth + 1)) | ||
if current.right: | ||
stack.append((current.right, depth + 1)) | ||
|
||
return max_depth |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
""" | ||
Constraints: | ||
- 1 <= intervals.length <= 10^4 | ||
- intervals[i].length == 2 | ||
- 0 <= starti <= endi <= 10^4 | ||
|
||
Time Complexity: | ||
- | ||
|
||
Space Complexity: | ||
- | ||
|
||
풀이방법: | ||
1. | ||
""" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
""" | ||
Constraints: | ||
- The number of nodes in the list is in the range [1, 5 * 10^4]. | ||
- 1 <= Node.val <= 1000 | ||
|
||
Time Complexity: O(n) | ||
- 리스트를 한 번씩 순회하면서 알고리즘의 각 단계를 수행함 | ||
|
||
Space Complexity: O(1) | ||
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. 저는 공간복잡도를 O(n) 으로 풀었는데, 투포인터를 사용해서 O(1) 으로 줄인점이 흥미롭네요! |
||
- 정해진 개수의 변수 외에는 추가 공간을 사용하지 않음 | ||
|
||
풀이방법: | ||
1. 중간 지점 찾기 | ||
- slow/fast 포인터를 사용하여 중간 지점 찾기 | ||
2. 뒷부분 뒤집기 | ||
- prev, curr 포인터로 링크드 리스트의 방향 전환 | ||
- next_temp에 다음 노드를 저장한 후 방향 변경 | ||
3. 앞부분과 뒷부분 합치기 | ||
- 두 리스트의 시작점(first, second)부터 시작 | ||
- temp1, temp2에 다음 노드 저장 | ||
- 포인터들을 번갈아가며 연결함 | ||
""" | ||
# Definition for singly-linked list. | ||
# class ListNode: | ||
# def __init__(self, val=0, next=None): | ||
# self.val = val | ||
# self.next = next | ||
class Solution: | ||
def reorderList(self, head: Optional[ListNode]) -> None: | ||
""" | ||
Do not return anything, modify head in-place instead. | ||
""" | ||
# 중간 지점 찾기 | ||
slow = head | ||
fast = head | ||
while fast and fast.next: | ||
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. 토끼와 거북이 알고리즘의 컨셉과 비슷하게 배열의 중간점을 찾는게 인상적이네요. |
||
slow = slow.next | ||
fast = fast.next.next | ||
|
||
# 뒷부분 뒤집기 | ||
prev = None | ||
curr = slow.next | ||
slow.next = None | ||
while curr: | ||
next_temp = curr.next | ||
curr.next = prev | ||
prev = curr | ||
curr = next_temp | ||
|
||
# 앞부분과 뒷부분 합치기 | ||
first = head | ||
second = prev | ||
while second: | ||
temp1 = first.next | ||
temp2 = second.next | ||
|
||
first.next = second | ||
second.next = temp1 | ||
|
||
first = temp1 | ||
second = temp2 | ||
|
||
|
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.
전 global variable를 사용하여 dfs에서 maxDepth 를 갱신하는 식으로 했는데, 이렇게 풀면 메소드 단위에서 답을 얻을 수 있어 더 좋은것 같습니다!