File tree Expand file tree Collapse file tree 4 files changed +204
-0
lines changed
maximum-depth-of-binary-tree Expand file tree Collapse file tree 4 files changed +204
-0
lines changed Original file line number Diff line number Diff line change 1+ """
2+ Valid Tree의 조건:
3+ 1. 모든 노드가 연결되어 있어야 함
4+ 2. 사이클이 없어야 함
5+ 3. edge의 개수는 n-1개
6+
7+ Time Complexity: O(V + E)
8+ - V: 노드의 개수
9+ - E: edge의 개수
10+
11+ Space Complexity: O(V)
12+ - 노드 방문 여부를 저장하는 visited set 사용
13+
14+ 풀이방법:
15+ 1. 기본 조건 체크: edge의 개수는 n-1개
16+ 2. 각 노드별로 연결된 노드들의 정보를 저장
17+ - 무방향 그래프이므로 양쪽 모두 저장
18+ 3. DFS로 노드 탐색
19+ - 0번 노드부터 시작해서 연결된 모든 노드를 방문
20+ - 이미 방문한 노드는 재방문하지 않음
21+ 4. 모든 노드 방문 확인
22+ - visited의 크기가 n과 같다면 모든 노드가 연결된 것 -> valid tree
23+ """
24+ def validTree (n , edges ):
25+ if len (edges ) != n - 1 :
26+ return False
27+
28+ adj = [[] for _ in range (n )]
29+ for a , b in edges :
30+ adj [a ].append (b )
31+ adj [b ].append (a )
32+
33+ visited = set ()
34+
35+ def dfs (node ):
36+ if node in visited :
37+ return
38+
39+ visited .add (node )
40+
41+ for next_node in adj [node ]:
42+ dfs (next_node )
43+
44+ dfs (0 )
45+ return len (visited ) == n
46+
Original file line number Diff line number Diff line change 1+ """
2+ Constraints:
3+ - The number of nodes in the tree is in the range [0, 10^4].
4+ - -100 <= Node.val <= 100
5+
6+ Time Complexity: O(N)
7+ - N은 트리의 노드 수
8+ - 모든 노드를 한 번씩 방문하기 때문
9+
10+ Space Complexity: O(H)
11+ - H는 트리의 높이
12+ - 재귀 호출로 인한 호출 스택의 최대 깊이가 트리의 높이와 같음
13+
14+ 풀이방법:
15+ 1. Base case: root가 None인 경우 0을 반환
16+ 2. 재귀를 활용하여 왼쪽과 오른쪽 서브트리 깊이를 각각 계산
17+ 3. 두 서브트리의 깊이 중 최대값에 1을 더해서 반환 (현재 노드의 깊이를 포함)
18+ """
19+ # Definition for a binary tree node.
20+ # class TreeNode:
21+ # def __init__(self, val=0, left=None, right=None):
22+ # self.val = val
23+ # self.left = left
24+ # self.right = right
25+
26+ # Solution 1: 재귀
27+ class Solution :
28+ def maxDepth (self , root : Optional [TreeNode ]) -> int :
29+ if root is None :
30+ return 0
31+
32+ left_depth = self .maxDepth (root .left )
33+ right_depth = self .maxDepth (root .right )
34+
35+ return max (left_depth , right_depth ) + 1
36+
37+ # Solution 2: 반복문
38+ class Solution :
39+ def maxDepth (self , root : Optional [TreeNode ]) -> int :
40+ if root is None :
41+ return 0
42+
43+ stack = [(root , 1 )]
44+ max_depth = 0
45+
46+ while stack :
47+ current , depth = stack .pop ()
48+
49+ max_depth = max (max_depth , depth )
50+
51+ if current .left :
52+ stack .append ((current .left , depth + 1 ))
53+ if current .right :
54+ stack .append ((current .right , depth + 1 ))
55+
56+ return max_depth
Original file line number Diff line number Diff line change 1+ """
2+ Constraints:
3+ - 1 <= intervals.length <= 10^4
4+ - intervals[i].length == 2
5+ - 0 <= starti <= endi <= 10^4
6+
7+ Time Complexity: O(nlogn)
8+ - 정렬에 nlogn, 순회에 n이 필요하므로 전체는 O(nlogn)
9+
10+ Space Complexity: O(n)
11+ - 최악의 경우 모든 구간이 겹치지 않아 n개의 구간을 저장해야 함
12+
13+ 풀이방법:
14+ 0. intervals를 시작점 기준으로 정렬
15+ 1. merged 배열을 intervals의 첫 번째 구간으로 초기화
16+ 2. intervals의 두 번째 구간부터 순회하면서:
17+ - 현재 구간의 시작점이 merged 배열의 마지막 구간의 끝점보다 작거나 같으면 병합
18+ - 병합할 때는 끝점을 두 구간의 끝점 중 더 큰 값으로 설정
19+ 3. 현재 구간이 merged의 마지막 구간과 겹치지 않으면 그대로 merged에 추가
20+ 4. 2-3을 반복하여 모든 구간을 처리함
21+ """
22+ class Solution :
23+ def merge (self , intervals : List [List [int ]]) -> List [List [int ]]:
24+ if not intervals :
25+ return []
26+
27+ intervals .sort (key = lambda x : x [0 ])
28+
29+ merged = [intervals [0 ]]
30+
31+ for interval in intervals [1 :]:
32+ if interval [0 ] <= merged [- 1 ][1 ]:
33+ merged [- 1 ][1 ] = max (merged [- 1 ][1 ], interval [1 ])
34+
35+ else :
36+ merged .append (interval )
37+
38+ return merged
39+
Original file line number Diff line number Diff line change 1+ """
2+ Constraints:
3+ - The number of nodes in the list is in the range [1, 5 * 10^4].
4+ - 1 <= Node.val <= 1000
5+
6+ Time Complexity: O(n)
7+ - 리스트를 한 번씩 순회하면서 알고리즘의 각 단계를 수행함
8+
9+ Space Complexity: O(1)
10+ - 정해진 개수의 변수 외에는 추가 공간을 사용하지 않음
11+
12+ 풀이방법:
13+ 1. 중간 지점 찾기
14+ - slow/fast 포인터를 사용하여 중간 지점 찾기
15+ 2. 뒷부분 뒤집기
16+ - prev, curr 포인터로 링크드 리스트의 방향 전환
17+ - next_temp에 다음 노드를 저장한 후 방향 변경
18+ 3. 앞부분과 뒷부분 합치기
19+ - 두 리스트의 시작점(first, second)부터 시작
20+ - temp1, temp2에 다음 노드 저장
21+ - 포인터들을 번갈아가며 연결함
22+ """
23+ # Definition for singly-linked list.
24+ # class ListNode:
25+ # def __init__(self, val=0, next=None):
26+ # self.val = val
27+ # self.next = next
28+ class Solution :
29+ def reorderList (self , head : Optional [ListNode ]) -> None :
30+ """
31+ Do not return anything, modify head in-place instead.
32+ """
33+ # 중간 지점 찾기
34+ slow = head
35+ fast = head
36+ while fast and fast .next :
37+ slow = slow .next
38+ fast = fast .next .next
39+
40+ # 뒷부분 뒤집기
41+ prev = None
42+ curr = slow .next
43+ slow .next = None
44+ while curr :
45+ next_temp = curr .next
46+ curr .next = prev
47+ prev = curr
48+ curr = next_temp
49+
50+ # 앞부분과 뒷부분 합치기
51+ first = head
52+ second = prev
53+ while second :
54+ temp1 = first .next
55+ temp2 = second .next
56+
57+ first .next = second
58+ second .next = temp1
59+
60+ first = temp1
61+ second = temp2
62+
63+
You can’t perform that action at this time.
0 commit comments