File tree Expand file tree Collapse 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 Expand file tree Collapse file tree 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