Skip to content

Commit a9c447d

Browse files
authored
week10 (#2269)
1 parent 0e8a9a4 commit a9c447d

3 files changed

Lines changed: 138 additions & 0 deletions

File tree

course-schedule/jaejeong1.kt

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import java.util.LinkedList
2+
import java.util.Queue
3+
4+
class `Course-Schedule` {
5+
fun canFinish(numCourses: Int, prerequisites: Array<IntArray>): Boolean {
6+
// 시간복잡도: O(N), 공간복잡도: O(N)
7+
8+
// 그래프와 선이수 과목 개수 배열 초기화
9+
val adj = Array(numCourses) { mutableListOf<Int>() }
10+
val indegree = IntArray(numCourses)
11+
12+
// 데이터 채우기 (preCourse 를 들어야 course 를 들을 수 있음)
13+
// indegree[course] 는 course 를 듣기 위한 선이수 과목 개수
14+
for (pre in prerequisites) {
15+
val course = pre[0]
16+
val preCourse = pre[1]
17+
18+
adj[preCourse].add(course)
19+
indegree[course]++
20+
}
21+
22+
// 선이수 과목 개수가 0인 과목을 큐에 추가
23+
val queue: Queue<Int> = LinkedList()
24+
for (i in 0 until numCourses) {
25+
if (indegree[i] == 0) {
26+
queue.offer(i)
27+
}
28+
}
29+
30+
var completedCourses = 0
31+
32+
while (queue.isNotEmpty()) {
33+
val current = queue.poll()
34+
completedCourses++
35+
// 완료한 과목을 선이수 과목으로 갖는 과목들의 선이수 과목 개수를 차감
36+
for (nextCourse in adj[current]) {
37+
indegree[nextCourse]--
38+
// 선이수 과목 개수가 0이 되면 큐에 추가
39+
if (indegree[nextCourse] == 0) {
40+
queue.offer(nextCourse)
41+
}
42+
}
43+
}
44+
// 완료한 과목 개수와 입력 과목 개수가 같은지
45+
return completedCourses == numCourses
46+
}
47+
}

invert-binary-tree/jaejeong1.kt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class TreeNode(var `val`: Int) {
2+
var left: TreeNode? = null
3+
var right: TreeNode? = null
4+
}
5+
6+
class InvertBinaryTree {
7+
fun invertTree(root: TreeNode?): TreeNode? {
8+
// 이진 트리의 root 를 주면, 트리를 뒤집고, 그것의 Root를 반환해라
9+
// 재귀적으로 left, right 를 바꾸면 된다. child가 둘다 null 이면 종료
10+
// 시간복잡도: O(N), 공간복잡도: O(1)
11+
if (root == null) return null
12+
13+
if (root.left == null && root.right == null) {
14+
return root
15+
}
16+
17+
val temp = root.left
18+
root.left = root.right
19+
root.right = temp
20+
21+
invertTree(root.left)
22+
invertTree(root.right)
23+
24+
return root
25+
}
26+
27+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
class `Search-in-Rotated-Sorted-Array` {
2+
fun search(nums: IntArray, target: Int): Int {
3+
// log n -> 이진 탐색
4+
// 이진 탐색 -> 왼쪽은 작고, 오른쪽은 크다
5+
// 그렇다면.. 회전된 인덱스 기준으로 잘라서 좌우에서 각각 이진 탐색하면 가능하다
6+
// 회전된 인덱스 어떻게 찾나? -> 이진 탐색해서 좌측이 더 크거나, 우측이 더 작으면 우측이 인덱스다
7+
8+
// 1단계: 이진 탐색해서 회전한 인덱스 찾기
9+
// 2단계: 회전한 인덱스 기준으로 좌우 자르고, 각각 이진 탐색하기
10+
// 3단계: 둘다 없으면 -1, 좌측 또는 우측에서 답 찾아서 반환
11+
// 시간복잡도: O(log n), 공간복잡도: O(1)
12+
13+
val rotatedIndex = findRotatedIndex(nums)
14+
val index = binarySearch(nums, 0, rotatedIndex - 1, target)
15+
// 왼쪽에 답이 있는지
16+
if (index > -1) {
17+
return index
18+
}
19+
// 없으면 오른쪽 답 탐색해서 반환
20+
return binarySearch(nums, rotatedIndex, nums.size - 1, target)
21+
}
22+
23+
fun findRotatedIndex(nums: IntArray): Int {
24+
// nums[0] 이 nums[mid]보다 크면 rotated index 는 왼쪽에 있음
25+
// 정렬되어있다면 위 조건이 될 수 없기 때문
26+
var left = 0
27+
var right = nums.size - 1
28+
while (left <= right) {
29+
val mid = left + (right - left) / 2
30+
// 좌측 값이 더 크면 rotated index
31+
if (0 < mid && nums[mid - 1] > nums[mid]) {
32+
return mid
33+
}
34+
// 왼쪽이 정렬되었는지
35+
if (nums[0] <= nums[mid]) {
36+
left = mid + 1
37+
}
38+
// 오른쪽이 정렬되었는지
39+
else {
40+
right = mid - 1
41+
}
42+
}
43+
return 0
44+
}
45+
46+
fun binarySearch(nums: IntArray, left: Int, right: Int, target: Int): Int {
47+
var left = left
48+
var right = right
49+
50+
while (left <= right) {
51+
val mid = left + (right - left) / 2
52+
if (nums[mid] == target) {
53+
return mid
54+
}
55+
if (nums[mid] < target) {
56+
left = mid + 1
57+
}
58+
else {
59+
right = mid - 1
60+
}
61+
}
62+
return -1
63+
}
64+
}

0 commit comments

Comments
 (0)