Skip to content
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

[moonhyeok] Week10 #1015

Merged
merged 4 commits into from
Feb 15, 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
36 changes: 36 additions & 0 deletions invert-binary-tree/mike2ox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Source: https://leetcode.com/problems/invert-binary-tree/
* 풀이방법: 재귀를 이용하여 트리를 뒤집음
*
* 시간복잡도: O(n) - n은 트리의 노드 수
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

재귀를 통해 풀어주셨군요! 👍 코드에서는 TreeNode를 새로 만들어서 return하는데 in-place로 구현할 수도 있을것같아요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감사합니다. in-place로 바로 결과를 보낼 수 있는걸 잊었네요 ㅎㅎ

* 공간복잡도: O(n) - 재귀 호출에 따른 스택 메모리
*
* 다른 풀이방법
* - BFS를 이용하여 풀이
* - 스택을 이용하여 풀이
*/

/**
* 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)
* }
* }
*/

function invertTree(root: TreeNode | null): TreeNode | null {
if (!root) return null;

const result = new TreeNode(
root.val,
invertTree(root.right),
invertTree(root.left)
);
return result;
}
21 changes: 21 additions & 0 deletions jump-game/mike2ox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Source: https://leetcode.com/problems/jump-game/
* 풀이방법: 그리디로 접근
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오.. 역으로 도착점을 당겨오는 풀이는 아이디어가 정말 새롭네요!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DFS로 그냥 해봤는데 시간오버떠서 뭔가 이미 도착했다는 전제하에 역으로 출발점을 찾는 식으로 하니까 해결됐습니다 ㅎㅎ..
PS할 때마다 이건 어떤 풀이법이 좋은지 찾는게 참 헷갈리네요

*
* 시간복잡도: O(n) - nums의 요소들을 다 방문할 수 있음
* 공간복잡도: O(1) - 특정 위치만 기억해둘 필요가 있음
*
* 다른 풀이
* - DFS로 처음에 접근했으나 시간 오버로 인해 Fail
*/

function canJump(nums: number[]): boolean {
let goal = nums.length - 1;
for (let i = nums.length - 1; i >= 0; i--) {
const pos = nums[i];
if (pos + i >= goal) {
goal = i;
}
}
return goal === 0;
}
48 changes: 48 additions & 0 deletions merge-k-sorted-lists/mike2ox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* Source: https://leetcode.com/problems/merge-k-sorted-lists/
* 풀이방법: 모든 리스트들을 한곳에 넣고 재배치
*
* 시간복잡도: O(NlogN) - 모든 리스트를 순회(N), 정렬(NlogN) 하는데 드는 시간 고려
* 공간복잡도: O(N) - 기존 배열을 저장할 공간만 필요
*/

/**
* 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)
* }
* }
*/

function mergeKLists(lists: Array<ListNode | null>): ListNode | null {
if (!lists?.length) return null;
let merged = [];

for (let i = 0; i < lists.length; i++) {
let cursor = lists[i];
while (cursor != null) {
merged.push(cursor.val);
cursor = cursor.next;
}
}
let sorted = merged.sort((a, b) => (a < b ? -1 : 1));
let head = null;
let tail = null;

for (let i = 0; i < sorted.length; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

순회 내에서 분기를 타는것보다는, 순회에 들어가기 전에 초기화를 해주는 방향은 어땠을까요?
내부 분기의 복잡도도 제거하고 매 순회마다 분기를 확인하는 연산도 줄일 수 있을 것 같아서 의견 드려요!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

처음에 변수 선언과 동시에 초기화를 해줬었는데 순회 내부 로직이 안떠올라서 더 고민안하고 내버렸는데 리팩토링 한번 해보겠습니다 :)

const node = new ListNode(sorted[i], null);
if (head === null) {
head = node;
tail = node;
} else {
tail.next = node;
tail = node;
}
}

return head;
}
28 changes: 28 additions & 0 deletions search-in-rotated-sorted-array/mike2ox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Source: https://leetcode.com/problems/search-in-rotated-sorted-array/description/
* 풀이방법: 이진탐색을 구현해서 원하는 값을 찾음
*
* 시간복잡도: O(log n) - 매 반복마다 탐색 범위가 절반으로 줄어듦
* 공간복잡도: O(1) - 추가 공간을 사용하지 않고 포인터 변수만 사용
*
* 포인트
* - 문제에서 시간 복잡도를 O(log n)을 하라고 제한을 했기때문에 쉽게 이진탐색으로 풀어야 함을 파악함
*/

function search(nums: number[], target: number): number {
let left = 0;
let right = nums.length - 1;

while (left <= right) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

중요하지 않은 내용입니다!

while문 내부의 코드가 흐름상 분명 불필요한 사족 없이 잘 짜여진 코드인데,
개인적으로 저는 묘하게 답답하고 읽기 힘든 느낌이 들어요.

분기문을 한줄로 간단하게 쓰신것도 좋지만, 약간의 구분감을 주시는것도 읽는 사람들에게 도움이 되지 않을까 싶어요!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

너무 간단해서 중괄호를 제거했는데 그게 오히려 독이 됐군요. 가독성 부분을 더 신경써보겠습니다 :)

let mid = Math.floor((left + right) / 2);
if (nums[mid] === target) return mid;
else if (nums[mid] >= nums[left]) {
if (nums[left] <= target && target <= nums[mid]) right = mid - 1;
else left = mid + 1;
} else {
if (nums[mid] <= target && target <= nums[right]) left = mid + 1;
else right = mid - 1;
}
}
return -1;
}