File tree 5 files changed +231
-0
lines changed
non-overlapping-intervals
number-of-connected-components-in-an-undirected-graph
remove-nth-node-from-end-of-list
5 files changed +231
-0
lines changed Original file line number Diff line number Diff line change
1
+ /**
2
+ *
3
+ * In graph theory, a tree is an undirected graph
4
+ * in which any two vertices are connected by exactly one path,
5
+ * or equivalently a connected acyclic undirected graph.
6
+ *
7
+ *
8
+ * 그래프가 valid tree인지 확인하는 함수
9
+ * @param {number } n - 노드의 수
10
+ * @param {number[][] } edges - 간선의 정보
11
+ * @returns {boolean } - 주어진 간선 정보로 만들어진 그래프가 트리인지 여부
12
+ *
13
+ * 시간 복잡도: O(n)
14
+ * - 모든 노드를 한 번씩 방문하여 그래프가 트리인지 확인
15
+ *
16
+ * 공간 복잡도: O(n)
17
+ * - 인접 리스트로 그래프, 방문배열
18
+ */
19
+ function validTree ( n : number , edges : number [ ] [ ] ) : boolean {
20
+ // 노드와 간선의 수 비교
21
+ if ( edges . length !== n - 1 ) {
22
+ return false
23
+ }
24
+
25
+ // 인접 리스트 형태로 그래프 생성
26
+ const grapph : Map < number , number [ ] > = new Map ( )
27
+ for ( let i = 0 ; i < n ; i ++ ) {
28
+ grapph . set ( i , [ ] ) ;
29
+ } ;
30
+ for ( const [ a , b ] of edges ) {
31
+ grapph . get ( a ) ?. push ( b )
32
+ grapph . get ( a ) ?. push ( b )
33
+ } ;
34
+
35
+ // 방문 배열 생성
36
+ const visited : boolean [ ] = new Array ( n ) . fill ( false ) ;
37
+
38
+ // DFS 깊이 우선 탐색
39
+ const dfs = ( node :number , parent : number ) : boolean => {
40
+ visited [ node ] = true ;
41
+ for ( const neighbor of grapph . get ( node ) ! ) {
42
+ if ( ! visited [ neighbor ] ) {
43
+ if ( ! dfs ( neighbor , node ) ) {
44
+ return false ;
45
+ }
46
+ } else if ( neighbor !== parent ) {
47
+ // 이미 방문한 노드가 부모가 아니면 사이클 발생
48
+ return false ;
49
+ }
50
+ }
51
+ return true ;
52
+ }
53
+
54
+ // DFS를 0번 노드부터 시작
55
+ // 시작 지점은 -1로 설정
56
+ if ( ! dfs ( 0 , - 1 ) ) {
57
+ return false ;
58
+ } ;
59
+
60
+ // 모든 노드가 방문되었는지 확인
61
+ for ( const isVisited of visited ) {
62
+ if ( ! isVisited ) {
63
+ return false ;
64
+ }
65
+ }
66
+
67
+ return true ;
68
+ }
69
+
Original file line number Diff line number Diff line change
1
+ /**
2
+ * 주어진 interval 배열에서 구간이 서로 겹치지 않기 위해서 제거해야 하는 최소한의 interval 수 구하기.
3
+ * @param {number[][] } intervals - interval 정보를 담는 2차원 배열 [start, end][]
4
+ * @returns {number } - 제거한 interval 최소 개수
5
+ */
6
+ function eraseOverlapIntervals ( intervals : number [ ] [ ] ) : number {
7
+ // interval의 end 기준으로 정렬
8
+ intervals . sort ( ( a , b ) => a [ 1 ] - b [ 1 ] ) ;
9
+
10
+ // 제거해야 하는 interval 수
11
+ let result = 0 ;
12
+ // 비교할 기준 interval
13
+ let prevInterval = intervals [ 0 ] ;
14
+
15
+ // 0 idx를 기준으로 하기 때문에 1번 idx부터 비교
16
+ for ( let i = 1 ; i < intervals . length ; i ++ ) {
17
+ // 이전 idx와 비교할 interval이 겹치는 경우
18
+ if ( intervals [ i ] [ 0 ] < prevInterval [ 1 ] ) {
19
+ result ++ ;
20
+ } else {
21
+ // 겹치치 않는경우 기준 interval 변경
22
+ prevInterval = intervals [ i ] ;
23
+ }
24
+ }
25
+
26
+
27
+ return result ;
28
+ }
29
+
Original file line number Diff line number Diff line change
1
+ /**
2
+ * 주어진 무방향 그래프의 연결된 컴포넌트(연결 요소)의 개수를 반환하는 함수
3
+ *
4
+ * @param {number } n - 노드의 수
5
+ * @param {number[][] } edges - 간선의 정보
6
+ * @returns {number } - 연결된 컴포넌트의 개수
7
+ *
8
+ * 시간 복잡도: O(n)
9
+ * - 모든 노드를 한 번씩 방문하여 연결된 컴포넌트의 개수를 계산
10
+ * 공간 복잡도: O(n)
11
+ * - 인접 리스트와 방문 배열 사용
12
+ */
13
+ function countComponents ( n : number , edges : number [ ] [ ] ) : number {
14
+ // 인접 리스트 형태로 그래프 생성
15
+ const graph : Map < number , number [ ] > = new Map ( ) ;
16
+ for ( let i = 0 ; i < n ; i ++ ) {
17
+ graph . set ( i , [ ] ) ;
18
+ }
19
+ for ( const [ a , b ] of edges ) {
20
+ graph . get ( a ) ?. push ( b ) ;
21
+ graph . get ( b ) ?. push ( a ) ;
22
+ }
23
+
24
+ // 방문 배열 생성
25
+ const visited : boolean [ ] = new Array ( n ) . fill ( false ) ;
26
+ let count = 0 ;
27
+
28
+ // 깊이 우선 탐색 (DFS)
29
+ const dfs = ( node : number ) : void => {
30
+ visited [ node ] = true ;
31
+ for ( const neighbor of graph . get ( node ) ! ) {
32
+ if ( ! visited [ neighbor ] ) {
33
+ dfs ( neighbor ) ;
34
+ }
35
+ }
36
+ }
37
+
38
+ // 모든 노드를 순회하며 아직 방문하지 않은 노드가 있으면 DFS 수행
39
+ for ( let i = 0 ; i < n ; i ++ ) {
40
+ if ( ! visited [ i ] ) {
41
+ // 새로운 연결 요소 발견
42
+ count ++ ;
43
+ dfs ( i ) ;
44
+ }
45
+ }
46
+
47
+ return count ;
48
+ }
49
+
Original file line number Diff line number Diff line change
1
+ /**
2
+ * Definition for singly-linked list.
3
+ * class ListNode {
4
+ * val: number;
5
+ * next: ListNode | null;
6
+ * constructor(val?: number, next?: ListNode | null) {
7
+ * this.val = (val === undefined ? 0 : val);
8
+ * this.next = (next === undefined ? null : next);
9
+ * }
10
+ * }
11
+ */
12
+
13
+ /**
14
+ * 주어진 단일 연결 리스트에서 뒤에서 N번째 노드를 제거하는 함수
15
+ * @param {ListNode | null } head - 연결 리스트의 시작 노드
16
+ * @param {number } n - 뒤에서 n번째 노드
17
+ * @returns {ListNode | null } - n번째 노드가 제거된 새로운 연결 리스트의 시작 노드
18
+ *
19
+ * 시간 복잡도: O(N)
20
+ * - 연결 리스트를 한 번 순회하여 길이를 찾고, 다시 한 번 순회하여 노드를 삭제 (2N)
21
+ * 공간 복잡도: O(1)
22
+ * - 추가적인 데이터 구조를 사용하지 않으며, 포인터만 사용하여 처리
23
+ */
24
+ function removeNthFromEnd ( head : ListNode | null , n : number ) : ListNode | null {
25
+ let headlength = 0 , cur = head ;
26
+
27
+ // 전체 길이 구하기
28
+ while ( cur ) {
29
+ headlength ++ ;
30
+ cur = cur . next ;
31
+ }
32
+
33
+ // 삭제할 노드 위치 계산 (length - n)
34
+ let dummy = new ListNode ( 0 , head ) ;
35
+ cur = dummy ;
36
+ for ( let i = 0 ; i < headlength - n ; i ++ ) {
37
+ cur = cur . next ;
38
+ }
39
+
40
+ // 노드 삭제 (n번째 노드 제거)
41
+ cur . next = cur . next ?. next || null ;
42
+
43
+ return dummy . next ;
44
+ }
45
+
Original file line number Diff line number Diff line change
1
+ /**
2
+ * Definition for a binary tree node.
3
+ * class TreeNode {
4
+ * val: number
5
+ * left: TreeNode | null
6
+ * right: TreeNode | null
7
+ * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
8
+ * this.val = (val===undefined ? 0 : val)
9
+ * this.left = (left===undefined ? null : left)
10
+ * this.right = (right===undefined ? null : right)
11
+ * }
12
+ * }
13
+ */
14
+
15
+ /**
16
+ * 두 트리가 같은 객체 트리인지 확인하는 함수
17
+ * @param {Treenode | null } p - 트리 노드 p
18
+ * @param {Treenode | null } q - 트리 노드 q
19
+ * @returns {boolean } - 두 트리가 동일한 구조인지 여부
20
+ *
21
+ * 시간 복잡도: O(n)
22
+ * - 최대 두 트리의 모든 노드를 한 번씩만 방문
23
+ * 공간 복잡도: O(n)
24
+ * - 재귀 호출로 트리 깊이 만큼의 공간이 필요
25
+ */
26
+ function isSameTree ( p : TreeNode | null , q : TreeNode | null ) : boolean {
27
+ // 같은 객체를 가리키고 있는 경우 true
28
+ if ( p === q ) return true ;
29
+
30
+ // 한쪽이 null 인 경우 false
31
+ if ( ! p || ! q ) return false ;
32
+
33
+ // 두 노드가 다른 경우 false
34
+ if ( p . val !== q . val ) return false ;
35
+
36
+ // 제귀를 통한 하위 트리 비교
37
+ return isSameTree ( p . left , q . left ) && isSameTree ( p . right , q . right ) ;
38
+ } ;
39
+
You can’t perform that action at this time.
0 commit comments