Skip to content
Open
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
47 changes: 47 additions & 0 deletions course-schedule/jaejeong1.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import java.util.LinkedList
import java.util.Queue

class `Course-Schedule` {
fun canFinish(numCourses: Int, prerequisites: Array<IntArray>): Boolean {
// 시간복잡도: O(N), 공간복잡도: O(N)

// 그래프와 선이수 과목 개수 배열 초기화
val adj = Array(numCourses) { mutableListOf<Int>() }
val indegree = IntArray(numCourses)

// 데이터 채우기 (preCourse 를 들어야 course 를 들을 수 있음)
// indegree[course] 는 course 를 듣기 위한 선이수 과목 개수
for (pre in prerequisites) {
val course = pre[0]
val preCourse = pre[1]

adj[preCourse].add(course)
indegree[course]++
}

// 선이수 과목 개수가 0인 과목을 큐에 추가
val queue: Queue<Int> = LinkedList()
for (i in 0 until numCourses) {
if (indegree[i] == 0) {
queue.offer(i)
}
}

var completedCourses = 0

while (queue.isNotEmpty()) {
val current = queue.poll()
completedCourses++
// 완료한 과목을 선이수 과목으로 갖는 과목들의 선이수 과목 개수를 차감
for (nextCourse in adj[current]) {
indegree[nextCourse]--
// 선이수 과목 개수가 0이 되면 큐에 추가
if (indegree[nextCourse] == 0) {
queue.offer(nextCourse)
}
}
}
// 완료한 과목 개수와 입력 과목 개수가 같은지
return completedCourses == numCourses
}
}
27 changes: 27 additions & 0 deletions invert-binary-tree/jaejeong1.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class TreeNode(var `val`: Int) {
var left: TreeNode? = null
var right: TreeNode? = null
}

class InvertBinaryTree {
fun invertTree(root: TreeNode?): TreeNode? {
// 이진 트리의 root 를 주면, 트리를 뒤집고, 그것의 Root를 반환해라
// 재귀적으로 left, right 를 바꾸면 된다. child가 둘다 null 이면 종료
// 시간복잡도: O(N), 공간복잡도: O(1)
if (root == null) return null

if (root.left == null && root.right == null) {
return root
}

val temp = root.left
root.left = root.right
root.right = temp

invertTree(root.left)
invertTree(root.right)

return root
}

}
64 changes: 64 additions & 0 deletions search-in-rotated-sorted-array/jaejeong1.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
class `Search-in-Rotated-Sorted-Array` {
fun search(nums: IntArray, target: Int): Int {
// log n -> 이진 탐색
// 이진 탐색 -> 왼쪽은 작고, 오른쪽은 크다
// 그렇다면.. 회전된 인덱스 기준으로 잘라서 좌우에서 각각 이진 탐색하면 가능하다
// 회전된 인덱스 어떻게 찾나? -> 이진 탐색해서 좌측이 더 크거나, 우측이 더 작으면 우측이 인덱스다

// 1단계: 이진 탐색해서 회전한 인덱스 찾기
// 2단계: 회전한 인덱스 기준으로 좌우 자르고, 각각 이진 탐색하기
// 3단계: 둘다 없으면 -1, 좌측 또는 우측에서 답 찾아서 반환
// 시간복잡도: O(log n), 공간복잡도: O(1)

val rotatedIndex = findRotatedIndex(nums)
val index = binarySearch(nums, 0, rotatedIndex - 1, target)
// 왼쪽에 답이 있는지
if (index > -1) {
return index
}
// 없으면 오른쪽 답 탐색해서 반환
return binarySearch(nums, rotatedIndex, nums.size - 1, target)
}

fun findRotatedIndex(nums: IntArray): Int {
// nums[0] 이 nums[mid]보다 크면 rotated index 는 왼쪽에 있음
// 정렬되어있다면 위 조건이 될 수 없기 때문
var left = 0
var right = nums.size - 1
while (left <= right) {
val mid = left + (right - left) / 2
// 좌측 값이 더 크면 rotated index
if (0 < mid && nums[mid - 1] > nums[mid]) {
return mid
}
// 왼쪽이 정렬되었는지
if (nums[0] <= nums[mid]) {
left = mid + 1
}
// 오른쪽이 정렬되었는지
else {
right = mid - 1
}
}
return 0
}

fun binarySearch(nums: IntArray, left: Int, right: Int, target: Int): Int {
var left = left
var right = right

while (left <= right) {
val mid = left + (right - left) / 2
if (nums[mid] == target) {
return mid
}
if (nums[mid] < target) {
left = mid + 1
}
else {
right = mid - 1
}
}
return -1
}
}