-
-
Notifications
You must be signed in to change notification settings - Fork 195
[mallayon] Week 10 #1011
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
[mallayon] Week 10 #1011
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
e940453
add solution : 226. Invert Binary Tree
mmyeon 00be0fc
add solution : 55. Jump Game
mmyeon e3a00b4
add solution : 207. Course Schedule
mmyeon 4d28d87
add solution : 33. Search in Rotated Sorted Array
mmyeon e9d57a6
add solution : 23. Merge k Sorted Lists
mmyeon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/** | ||
* @link https://leetcode.com/problems/course-schedule/description/ | ||
* | ||
* 접근 방법 : | ||
* - 주어진 과목에서 선수 과목 사이클이 존재하는지 확인하기 위해서 dfs 사용 | ||
* - 사이클이 있다는 건 탐색 중에 다시 동일 과목이 등장한 경우니까, 과목별 결과 저장하기 위해서 visited 배열 사용 | ||
* | ||
* 시간복잡도 : O(n + e) | ||
* - n = 들어야 하는 과목 수 | ||
* - e = 선수 과목과 연결된 과목 수 | ||
* - 선수 과목 dfs 호출하고, 선수 과목과 연결된 과목도 호출함 | ||
* | ||
* 공간복잡도 : O(n + e) | ||
* - n = 들어야 하는 과목 수 | ||
* - e = 선수 과목과 연결된 과목 수 | ||
* - visited 배열 : O(n) | ||
* - Map : O(e) | ||
*/ | ||
|
||
function canFinish(numCourses: number, prerequisites: number[][]): boolean { | ||
// 선수 과목을 키, 후속 과목을 값으로 저장 | ||
const map = new Map<number, number[]>(); | ||
|
||
for (const [course, prerequisite] of prerequisites) { | ||
if (!map.has(prerequisite)) map.set(prerequisite, []); | ||
map.get(prerequisite)!.push(course); | ||
} | ||
|
||
// 이미 탐색중인 과목인지 확인하기 위한 배열 | ||
// 미탐색 : 0, 탐색중: 1, 탐색완료 : 2로 처리 | ||
const visited = Array(numCourses).fill(0); | ||
|
||
const dfs = (course: number) => { | ||
// 탐색중이면 사이클이 발생 | ||
if (visited[course] === 1) return false; | ||
// 탐색 완료인 과목은 사이클이 없는 상태니까 true 리턴 | ||
if (visited[course] === 2) return true; | ||
|
||
// 탐색 시작 | ||
// 탐색 중인 상태로 변경 | ||
visited[course] = 1; | ||
|
||
const nextCourses = map.get(course) ?? []; | ||
|
||
// 후속 과목 모두 체크 | ||
for (const nextCourse of nextCourses) { | ||
if (!dfs(nextCourse)) return false; | ||
} | ||
|
||
// 탐색 완료 상태로 변경 | ||
visited[course] = 2; | ||
return true; | ||
}; | ||
|
||
// 들어야 하는 모든 과목에 대해 dfs 호출 | ||
for (let i = 0; i < numCourses; i++) { | ||
// 미탐색 노드만 탐색하도록 처리 | ||
if (visited[i] === 0 && !dfs(i)) return false; | ||
} | ||
|
||
return true; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
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; | ||
} | ||
} | ||
|
||
/** | ||
* @link https://leetcode.com/problems/invert-binary-tree/description/ | ||
* | ||
* 접근 방법 : 깊이 우선 탐색(DFS) 사용 | ||
* - 각 노드의 좌우 자식 노드 swap 진행 | ||
* - 왼쪽, 오른쪽 서브트리에 대해 재귀적으로 호출 | ||
* | ||
* 시간복잡도 : O(n) | ||
* - n은 노드의 개수, 주어진 노드 만큼 순회 | ||
* | ||
* 공간복잡도 : O(h) | ||
* - h : 트리의 높이 | ||
* - 호출 스택 최대 트리 높이만큼 쌓임 | ||
*/ | ||
function invertTree(root: TreeNode | null): TreeNode | null { | ||
if (!root) return root; | ||
|
||
[root.left, root.right] = [root.right, root.left]; | ||
invertTree(root.left); | ||
invertTree(root.right); | ||
|
||
return root; | ||
} | ||
|
||
/** | ||
* | ||
* 접근 방법 : 너비 우선 탐색(BFS) 사용 | ||
* - root 노드를 큐에 담고, 큐가 빌 때까지 좌우 자식 노드 swap과 큐에 추가 하는 로직 반복하기 | ||
* | ||
* 시간복잡도 : O(n) | ||
* - n: 트리 노드의 개수 | ||
* - 모든 노드를 한 번 씩 방문하고 swap 작업 진행 | ||
* | ||
* 공간복잡도 : O(n) | ||
* - 최악의 경우 치우친 트리인 경우 모든 노드 순차적으로 큐에 저장 | ||
*/ | ||
function invertTree(root: TreeNode | null): TreeNode | null { | ||
if (!root) return root; | ||
|
||
const queue = [root]; | ||
|
||
while (queue.length) { | ||
const node = queue.shift()!; | ||
|
||
[node.left, node.right] = [node.right, node.left]; | ||
|
||
if (node.left) queue.push(node.left); | ||
if (node.right) queue.push(node.right); | ||
} | ||
|
||
return root; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/** | ||
*@link https://leetcode.com/problems/jump-game/description/ | ||
* | ||
* 접근 방법 : | ||
* - 현재 인덱스에서 최대로 도달할 수 있는 인덱스를 갱신하여 마지막 인덱스에 도달할 수 있는지 체크 | ||
* - 최대 도달할 수 있는 인덱스가 현재 인덱스보다 작으면, 이후는 확인할 필요 없으니까 false 리턴 | ||
* | ||
* 시간복잡도 : O(n) | ||
* - n = 배열의 길이, 배열 1회만 순회 | ||
* | ||
* 공간복잡도 : O(1) | ||
* - 고정된 변수만 사용 | ||
*/ | ||
|
||
function canJump(nums: number[]): boolean { | ||
const lastIndex = nums.length - 1; | ||
let maxReachableIndex = 0; | ||
|
||
for (let i = 0; i < nums.length; i++) { | ||
if (maxReachableIndex < i) return false; | ||
|
||
maxReachableIndex = Math.max(maxReachableIndex, i + nums[i]); | ||
|
||
if (lastIndex <= maxReachableIndex) return true; | ||
} | ||
|
||
return false; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
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; | ||
} | ||
} | ||
|
||
/** | ||
* @link https://leetcode.com/problems/merge-k-sorted-lists/description/ | ||
* | ||
* 접근 방법 : | ||
* - 리스트를 배열에 넣고, 최소값을 가진 노드 찾기 | ||
* - 최소값 노드를 더미 노드에 연결한 뒤 제거하고, 최소값 노드의 다음 노드를 다시 배열에 추가하기 | ||
* - 배열 길이가 0이 될 때까지 반복하기 | ||
* | ||
* 시간복잡도 : O(n * k) | ||
* - n = 총 노드의 개수 | ||
* - k = 리스트의 개수 | ||
* - 최소값 찾고, 최소값 제거하는 로직: O(k) | ||
* - 위의 연산을 총 n번 실행 | ||
* | ||
* 공간복잡도 : O(k) | ||
* - k = 리스트 개수 | ||
* - minList 배열의 크기가 최대 K개까지 유지 | ||
* | ||
*/ | ||
|
||
function mergeKLists(lists: Array<ListNode | null>): ListNode | null { | ||
const minList: ListNode[] = []; | ||
|
||
for (const list of lists) { | ||
if (list !== null) minList.push(list); | ||
} | ||
|
||
const dummy = new ListNode(); | ||
let tail = dummy; | ||
|
||
while (minList.length > 0) { | ||
const minIndex = getMinIndex(minList); | ||
const minNode = minList.splice(minIndex, 1)[0]; | ||
|
||
tail.next = minNode; | ||
tail = tail.next; | ||
|
||
if (minNode.next) minList.push(minNode.next); | ||
} | ||
|
||
return dummy.next; | ||
} | ||
|
||
function getMinIndex(nodes: ListNode[]): number { | ||
let minIndex = 0; | ||
|
||
for (let i = 1; i < nodes.length; i++) { | ||
if (nodes[i].val < nodes[minIndex].val) minIndex = i; | ||
} | ||
|
||
return minIndex; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/** | ||
* @link https://leetcode.com/problems/search-in-rotated-sorted-array/description/ | ||
* | ||
* 접근 방법 : | ||
* - O(log n)으로 풀어야 하니까 이진 탐색으로 탐색 범위 좁히기 | ||
* - pivot 인덱스 찾고, pivot 기준으로 target이 속하는 범위에서 탐색하기 | ||
* | ||
* 시간복잡도 : O(log n) | ||
* - 배열 범위를 계속 줄여나가므로 O(log n) | ||
* | ||
* 공간복잡도 : O(1) | ||
* - 고정된 변수만 사용 | ||
*/ | ||
|
||
function search(nums: number[], target: number): number { | ||
let start = 0, | ||
end = nums.length - 1; | ||
|
||
// pivot 인덱스 찾기 | ||
while (start < end) { | ||
const mid = Math.floor((start + end) / 2); | ||
if (nums[mid] > nums[end]) { | ||
start = mid + 1; | ||
} else { | ||
end = mid; | ||
} | ||
} | ||
|
||
const pivot = start; | ||
start = 0; | ||
end = nums.length - 1; | ||
|
||
// pivot 기준으로 target이 포함된 범위로 좁히기 | ||
if (nums[pivot] <= target && target <= nums[end]) { | ||
start = pivot; | ||
} else { | ||
end = pivot - 1; | ||
} | ||
|
||
// target 인덱스 찾기 위해서 이진 탐색 실행 | ||
while (start <= end) { | ||
const mid = Math.floor((start + end) / 2); | ||
|
||
if (nums[mid] === target) return mid; | ||
if (nums[mid] < target) { | ||
start = mid + 1; | ||
} else { | ||
end = mid - 1; | ||
} | ||
} | ||
|
||
return -1; | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
non-null assertion operator 라는 것을 사용할 수도 있군요. 새로운 걸 배우고 갑니다. 감사합니다.