Skip to content

[gomgom22] Week12 #1063

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

Merged
merged 6 commits into from
Mar 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions graph-valid-tree/Yjason-K.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
*
* In graph theory, a tree is an undirected graph
* in which any two vertices are connected by exactly one path,
* or equivalently a connected acyclic undirected graph.
*
*
* 그래프가 valid tree인지 확인하는 함수
* @param {number} n - 노드의 수
* @param {number[][]} edges - 간선의 정보
* @returns {boolean} - 주어진 간선 정보로 만들어진 그래프가 트리인지 여부
*
* 시간 복잡도: O(n)
* - 모든 노드를 한 번씩 방문하여 그래프가 트리인지 확인
*
* 공간 복잡도: O(n)
* - 인접 리스트로 그래프, 방문배열
*/
function validTree(n: number, edges: number[][]): boolean {
// 노드와 간선의 수 비교
if (edges.length !== n-1) {
return false
}

// 인접 리스트 형태로 그래프 생성
const grapph: Map<number, number[]> = new Map()
for (let i = 0; i < n; i++) {
grapph.set(i, []);
};
for (const [a, b] of edges) {
grapph.get(a)?.push(b)
grapph.get(a)?.push(b)
};

// 방문 배열 생성
const visited: boolean[] = new Array(n).fill(false);

// DFS 깊이 우선 탐색
const dfs = (node:number, parent: number): boolean => {
visited[node] = true;
for (const neighbor of grapph.get(node)!) {
if (!visited[neighbor]) {
if (!dfs(neighbor, node)) {
return false;
}
} else if (neighbor !== parent) {
// 이미 방문한 노드가 부모가 아니면 사이클 발생
return false;
}
}
return true;
}

// DFS를 0번 노드부터 시작
// 시작 지점은 -1로 설정
if(!dfs(0, -1)) {
return false;
};

// 모든 노드가 방문되었는지 확인
for (const isVisited of visited) {
if (!isVisited) {
return false;
}
}

return true;
}

29 changes: 29 additions & 0 deletions non-overlapping-intervals/Yjason-K.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* 주어진 interval 배열에서 구간이 서로 겹치지 않기 위해서 제거해야 하는 최소한의 interval 수 구하기.
* @param {number[][]} intervals - interval 정보를 담는 2차원 배열 [start, end][]
* @returns {number} - 제거한 interval 최소 개수
*/
function eraseOverlapIntervals(intervals: number[][]): number {
// interval의 end 기준으로 정렬
intervals.sort((a, b) => a[1] - b[1]);

// 제거해야 하는 interval 수
let result = 0;
// 비교할 기준 interval
let prevInterval = intervals[0];

// 0 idx를 기준으로 하기 때문에 1번 idx부터 비교
for(let i=1; i < intervals.length; i++) {
// 이전 idx와 비교할 interval이 겹치는 경우
if(intervals[i][0] < prevInterval[1]) {
result++;
} else {
// 겹치치 않는경우 기준 interval 변경
prevInterval = intervals[i];
}
}


return result;
}

49 changes: 49 additions & 0 deletions number-of-connected-components-in-an-undirected-graph/Yjason-K.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* 주어진 무방향 그래프의 연결된 컴포넌트(연결 요소)의 개수를 반환하는 함수
*
* @param {number} n - 노드의 수
* @param {number[][]} edges - 간선의 정보
* @returns {number} - 연결된 컴포넌트의 개수
*
* 시간 복잡도: O(n)
* - 모든 노드를 한 번씩 방문하여 연결된 컴포넌트의 개수를 계산
* 공간 복잡도: O(n)
* - 인접 리스트와 방문 배열 사용
*/
function countComponents(n: number, edges: number[][]): number {
// 인접 리스트 형태로 그래프 생성
const graph: Map<number, number[]> = new Map();
for (let i = 0; i < n; i++) {
graph.set(i, []);
}
for (const [a, b] of edges) {
graph.get(a)?.push(b);
graph.get(b)?.push(a);
}

// 방문 배열 생성
const visited: boolean[] = new Array(n).fill(false);
let count = 0;

// 깊이 우선 탐색 (DFS)
const dfs = (node: number): void => {
visited[node] = true;
for (const neighbor of graph.get(node)!) {
if (!visited[neighbor]) {
dfs(neighbor);
}
}
}

// 모든 노드를 순회하며 아직 방문하지 않은 노드가 있으면 DFS 수행
for (let i = 0; i < n; i++) {
if (!visited[i]) {
// 새로운 연결 요소 발견
count++;
dfs(i);
}
}

return count;
}

45 changes: 45 additions & 0 deletions remove-nth-node-from-end-of-list/Yjason-K.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* Definition for singly-linked list.
* class ListNode {
* val: number;
* next: ListNode | null;
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val === undefined ? 0 : val);
* this.next = (next === undefined ? null : next);
* }
* }
*/

/**
* 주어진 단일 연결 리스트에서 뒤에서 N번째 노드를 제거하는 함수
* @param {ListNode | null} head - 연결 리스트의 시작 노드
* @param {number} n - 뒤에서 n번째 노드
* @returns {ListNode | null} - n번째 노드가 제거된 새로운 연결 리스트의 시작 노드
*
* 시간 복잡도: O(N)
* - 연결 리스트를 한 번 순회하여 길이를 찾고, 다시 한 번 순회하여 노드를 삭제 (2N)
* 공간 복잡도: O(1)
* - 추가적인 데이터 구조를 사용하지 않으며, 포인터만 사용하여 처리
*/
function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null {
let headlength = 0, cur = head;

// 전체 길이 구하기
while (cur) {
headlength++;
cur = cur.next;
}

// 삭제할 노드 위치 계산 (length - n)
let dummy = new ListNode(0, head);
cur = dummy;
for (let i = 0; i < headlength - n; i++) {
cur = cur.next;
}

// 노드 삭제 (n번째 노드 제거)
cur.next = cur.next?.next || null;

return dummy.next;
}

39 changes: 39 additions & 0 deletions same-tree/Yjason-K.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Definition for a binary tree node.
* class TreeNode {
* val: number
* left: TreeNode | null
* right: TreeNode | null
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
* }
*/

/**
* 두 트리가 같은 객체 트리인지 확인하는 함수
* @param {Treenode | null} p - 트리 노드 p
* @param {Treenode | null} q - 트리 노드 q
* @returns {boolean} - 두 트리가 동일한 구조인지 여부
*
* 시간 복잡도: O(n)
* - 최대 두 트리의 모든 노드를 한 번씩만 방문
* 공간 복잡도: O(n)
* - 재귀 호출로 트리 깊이 만큼의 공간이 필요
*/
function isSameTree(p: TreeNode | null, q: TreeNode | null): boolean {
// 같은 객체를 가리키고 있는 경우 true
if (p === q) return true;

// 한쪽이 null 인 경우 false
if (!p || !q) return false;

// 두 노드가 다른 경우 false
if(p.val !== q.val) return false;

// 제귀를 통한 하위 트리 비교
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
};