File tree 4 files changed +204
-0
lines changed
maximum-depth-of-binary-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