Skip to content

Commit cf1925e

Browse files
authored
Merge branch 'DaleStudy:main' into main
2 parents 81db73c + 459ae30 commit cf1925e

File tree

104 files changed

+3508
-4
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+3508
-4
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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+
// Time Complexity: O(n)
16+
// Space Complexity: O(h) where h is the height of the tree
17+
function maxPathSum(root: TreeNode | null): number {
18+
let maximumSum = -Infinity;
19+
20+
const dfs = (node: TreeNode | null) => {
21+
if (!node) return 0;
22+
23+
let leftResult = dfs(node.left);
24+
let rightResult = dfs(node.right);
25+
26+
leftResult = Math.max(0, leftResult);
27+
rightResult = Math.max(0, rightResult);
28+
29+
maximumSum = Math.max(maximumSum, node.val + leftResult + rightResult);
30+
31+
return node.val + Math.max(leftResult, rightResult);
32+
};
33+
34+
dfs(root);
35+
36+
return maximumSum;
37+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Definition for a binary tree node.
3+
* type TreeNode struct {
4+
* Val int
5+
* Left *TreeNode
6+
* Right *TreeNode
7+
* }
8+
*/
9+
func maxPathSum(root *TreeNode) int {
10+
ans, _ := solve(root)
11+
return ans
12+
}
13+
14+
func solve(root *TreeNode) (int, int) {
15+
if root == nil {
16+
return -30_000_000, -30_000_000
17+
}
18+
leftAns, leftRootAns := solve(root.Left)
19+
rightAns, rightRootAns := solve(root.Right)
20+
rootAns := root.Val + max(0, leftRootAns, rightRootAns,)
21+
ans := max(leftAns, rightAns, root.Val + max(0, leftRootAns,) + max(0, rightRootAns,))
22+
return ans, rootAns
23+
}

clone-graph/jinvicky.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import java.util.HashMap;
2+
import java.util.Map;
3+
4+
class Solution {
5+
public Node cloneGraph(Node node) {
6+
if (node == null) return null;
7+
8+
Map<Node, Node> map = new HashMap<>();
9+
return clone(node, map);
10+
}
11+
12+
private Node clone(Node node, Map<Node, Node> map) {
13+
if (map.containsKey(node)) {
14+
return map.get(node);
15+
}
16+
17+
Node clonedNode = new Node(node.val);
18+
map.put(node, clonedNode);
19+
20+
for (Node neighbor : node.neighbors) {
21+
clonedNode.neighbors.add(clone(neighbor, map));
22+
}
23+
24+
return clonedNode;
25+
}
26+
}

course-schedule/delight010.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
class Solution {
2+
// Time O(V + E)
3+
// Space O(V + E)
4+
func canFinish(_ numCourses: Int, _ prerequisites: [[Int]]) -> Bool {
5+
var indegree: [Int] = Array(repeating: 0, count: numCourses)
6+
var queue: [Int] = []
7+
var graph: [[Int]] = Array(repeating: [], count: numCourses)
8+
9+
for i in 0..<prerequisites.count {
10+
let degree = prerequisites[i].first!
11+
let graphIndex = prerequisites[i][1]
12+
indegree[degree] += 1
13+
graph[graphIndex].append(degree)
14+
}
15+
16+
for i in 0..<indegree.count {
17+
if indegree[i] == 0 {
18+
queue.append(i)
19+
}
20+
}
21+
22+
var count = 0
23+
24+
while !queue.isEmpty {
25+
let current = queue.removeFirst()
26+
count += 1
27+
for i in graph[current] {
28+
indegree[i] -= 1
29+
if indegree[i] == 0 {
30+
queue.append(i)
31+
}
32+
}
33+
}
34+
35+
return count == numCourses
36+
}
37+
}
38+

course-schedule/hi-rachel.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,104 @@ def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
5656
queue.append(neighbor)
5757

5858
return completed == numCourses
59+
60+
"""
61+
위상 정렬을 구하는 알고리즘
62+
1. DFS 기반 (스택을 쌓아 뒤집는 방식)
63+
2. Kahn 알고리즘 (진입차수 0부터 차례로 큐 처리)
64+
65+
Kahn 알고리즘이란?
66+
방향 그래프에서 진입차수(indegree)가 0인 정점부터 차례로 제거(큐에 넣어 꺼내기)하며 위상 순서를 만드는 방법.
67+
진입차수가 0인 정점이 하나도 없는데 아직 남은 정점이 있다면 사이클 존재 -> 위상 정렬 불가.
68+
69+
위상 순서: 방향 그래프에서 간선(u→v)이 있다면, 순서에서 u가 항상 v보다 앞에 나오는 정점들의 나열.
70+
진입차수: 정점으로 들어오는 간선의 개수.
71+
72+
73+
TC: O(V + E), V: 과목 수, E: prerequisite 관계 수
74+
SC: O(V + E), 그래프 + 진입차수 배열
75+
"""
76+
class Solution:
77+
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
78+
# 1) 그래프(인접 리스트)와 진입차수 배열 만들기
79+
adj = [[] for _ in range(numCourses)]
80+
indeg = [0] * numCourses
81+
for a, b in prerequisites: # b -> a (b를 먼저 들어야 a를 들을 수 있음)
82+
adj[b].append(a)
83+
indeg[a] += 1
84+
85+
# 2) 진입차수 0인 정점들로 큐 초기화
86+
q = deque([i for i in range(numCourses) if indeg[i] == 0])
87+
taken = 0 # 처리(수강) 완료한 과목 수
88+
89+
# 3) 큐에서 빼며 간선 제거(=후속 과목 진입차수 감소)
90+
while q:
91+
u = q.popleft()
92+
taken += 1
93+
for v in adj[u]:
94+
indeg[v] -= 1
95+
if indeg[v] == 0:
96+
q.append(v)
97+
98+
# 4) 모두 처리됐으면 사이클 없음
99+
return taken == numCourses
100+
101+
102+
"""
103+
DFS 기반
104+
TC: O(V + E), V: 과목 수, E: prerequisite 관계 수
105+
SC: O(V + E), 그래프 + 탐색 중인 과목 집합 + 수강 완료한 과목 집합
106+
"""
107+
class Solution:
108+
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
109+
graph = {i: [] for i in range(numCourses)}
110+
for crs, pre in prerequisites:
111+
# 선수 과목을 원소로 추가
112+
graph[crs].append(pre)
113+
114+
# 탐색중
115+
traversing = set()
116+
# 수강가능한 과목
117+
finished = set()
118+
119+
def can_finish(crs):
120+
if crs in traversing:
121+
return False
122+
if crs in finished:
123+
return True
124+
125+
traversing.add(crs)
126+
for pre in graph[crs]:
127+
if not can_finish(pre):
128+
return False
129+
traversing.remove(crs)
130+
finished.add(crs)
131+
return True
132+
133+
for crs in graph:
134+
if not can_finish(crs):
135+
return False
136+
return True
137+
138+
from functools import cache
139+
140+
# 줄인 코드
141+
class Solution:
142+
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
143+
graph = {i: [] for i in range(numCourses)}
144+
for crs, pre in prerequisites:
145+
graph[crs].append(pre)
146+
147+
traversing = set()
148+
149+
@cache
150+
def can_finish(crs):
151+
if crs in traversing:
152+
return False
153+
154+
traversing.add(crs)
155+
result = all(can_finish(pre) for pre in graph[crs])
156+
traversing.remove(crs)
157+
return result
158+
159+
return all(can_finish(crs) for crs in graph)

course-schedule/hu6r1s.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from collections import defaultdict
2+
3+
class Solution:
4+
# def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
5+
# for pre_x, pre_y in prerequisites:
6+
# if [pre_y, pre_x] in prerequisites:
7+
# return False
8+
# return True
9+
10+
11+
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
12+
d = defaultdict(list)
13+
14+
for x, y in prerequisites:
15+
d[x].append(y)
16+
17+
visited = set()
18+
finished = set()
19+
20+
def dfs(course):
21+
if course in visited:
22+
return False
23+
if course in finished:
24+
return True
25+
26+
visited.add(course)
27+
for v in d[course]:
28+
if not dfs(v):
29+
return False
30+
visited.remove(course)
31+
finished.add(course)
32+
return True
33+
34+
for course in list(d):
35+
if not dfs(course):
36+
return False
37+
return True

course-schedule/hyer0705.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
function canFinish(numCourses: number, prerequisites: number[][]): boolean {
2+
const graph: number[][] = Array.from({ length: numCourses }, () => []);
3+
const inDegree: number[] = Array(numCourses).fill(0);
4+
5+
for (const [course, prerequisite] of prerequisites) {
6+
graph[prerequisite].push(course);
7+
inDegree[course]++;
8+
}
9+
10+
// 지금 당장 수강할 수 있는 과목 목록
11+
const queue: number[] = [];
12+
13+
for (let i = 0; i < numCourses; i++) {
14+
if (inDegree[i] === 0) {
15+
queue.push(i);
16+
}
17+
}
18+
19+
const result: number[] = [];
20+
while (queue.length > 0) {
21+
const course = queue.shift()!;
22+
result.push(course);
23+
24+
for (const nextCourse of graph[course]) {
25+
inDegree[nextCourse]--;
26+
if (inDegree[nextCourse] === 0) {
27+
queue.push(nextCourse);
28+
}
29+
}
30+
}
31+
32+
if (result.length !== numCourses) return false;
33+
return true;
34+
}

course-schedule/yhkee0404.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
class Solution {
2+
func canFinish(_ numCourses: Int, _ prerequisites: [[Int]]) -> Bool {
3+
var adj: [[Int]] = Array(repeating: [], count: numCourses)
4+
for ab in prerequisites {
5+
adj[ab[0]].append(ab[1])
6+
}
7+
var visited = Array(repeating: 0, count: numCourses)
8+
var stack = Array(0..<numCourses)
9+
while !stack.isEmpty {
10+
let u = stack.last!
11+
if visited[u] == 2 {
12+
stack.removeLast()
13+
continue
14+
} else if visited[u] == 1 {
15+
visited[u] = 2
16+
stack.removeLast()
17+
continue
18+
}
19+
visited[u] = 1
20+
for v in adj[u] {
21+
if visited[v] == 1 {
22+
return false
23+
}
24+
if visited[v] == 2 {
25+
continue
26+
}
27+
stack.append(v)
28+
}
29+
}
30+
return true
31+
}
32+
}

0 commit comments

Comments
 (0)