Skip to content

[moonhyeok] Week9 #999

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 4 commits into from
Feb 9, 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
44 changes: 44 additions & 0 deletions find-minimum-in-rotated-sorted-array/mike2ox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* Source: https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/
* 풀이방법: 이진 탐색을 이용하여 최솟값을 찾음
*
* 시간복잡도: O(log n)
* 공간복잡도: O(1)
*/

function findMin(nums: number[]): number {
// 배열의 길이가 1인 경우
if (nums.length === 1) return nums[0];

let left: number = 0;
let right: number = nums.length - 1;

// 이미 정렬된 경우
if (nums[right] > nums[0]) {
return nums[0];
}

// 이진 탐색
while (left <= right) {
const mid: number = Math.floor((left + right) / 2);

// 최솟값을 찾는 조건들
if (nums[mid] > nums[mid + 1]) {
return nums[mid + 1];
}
if (nums[mid - 1] > nums[mid]) {
return nums[mid];
}

// 탐색 범위 조정
if (nums[mid] > nums[0]) {
// 최솟값은 중간점 이후에 있음
left = mid + 1;
} else {
// 최솟값은 중간점 이전에 있음
right = mid - 1;
}
}

return nums[0]; // 기본값 반환
}
39 changes: 39 additions & 0 deletions linked-list-cycle/mike2ox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Source: https://leetcode.com/problems/linked-list-cycle/
* 풀이방법: Set을 이용하여 방문한 노드를 저장하고 순회하면서 중복된 노드가 있는지 확인
*
* 시간복잡도: O(n)
* 공간복잡도: O(n)
*/

// 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 hasCycle(head: ListNode | null): boolean {
if (head === null) return false;

// 방문한 노드들을 저장할 Set
const addr = new Set<ListNode>();

// 첫 노드 추가
addr.add(head);
head = head.next;

// 리스트 순회
while (head !== null) {
// 이미 방문한 노드인 경우 cycle 존재
if (addr.has(head)) return true;

// 새로운 노드 추가
addr.add(head);
head = head.next;
}

return false;
}
40 changes: 40 additions & 0 deletions maximum-product-subarray/mike2ox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Source: https://leetcode.com/problems/maximum-product-subarray/
* 풀이방법: 현재 곱과 최대 곱을 비교하여 최대값을 구함
*
* 시간복잡도: O(n)
* 공간복잡도: O(1)
*
* 다른 풀이방법
* - DP를 이용하여 풀이
*/
function maxProduct(nums: number[]): number {
if (nums.length === 0) return 0;

let maxProduct = nums[0];
let currentProduct = 1;

// 왼쪽에서 오른쪽으로 순회
for (let i = 0; i < nums.length; i++) {
currentProduct *= nums[i];
maxProduct = Math.max(maxProduct, currentProduct);
// 현재 곱이 0이 되면 리셋
if (currentProduct === 0) {
currentProduct = 1;
}
}

currentProduct = 1;

// 오른쪽에서 왼쪽으로 순회
for (let i = nums.length - 1; i >= 0; i--) {
currentProduct *= nums[i];
maxProduct = Math.max(maxProduct, currentProduct);
// 현재 곱이 0이 되면 리셋
if (currentProduct === 0) {
currentProduct = 1;
}
}

return maxProduct;
}
75 changes: 75 additions & 0 deletions pacific-atlantic-water-flow/mike2ox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/**
* Source: https://leetcode.com/problems/pacific-atlantic-water-flow/
* 풀이방법: DFS를 이용하여 pacific과 atlantic에서 물이 흐르는 지점을 찾음
*
* 시간복잡도: O(n * m) (n: 행의 개수, m: 열의 개수)
* 공간복잡도: O(n * m)
*/

function pacificAtlantic(heights: number[][]): number[][] {
if (!heights || !heights[0]) return [];

const rows = heights.length;
const cols = heights[0].length;

// checklist
const pacific = new Set<string>();
const atlantic = new Set<string>();

// DFS
function dfs(
row: number,
col: number,
prevHeight: number,
visited: Set<string>
) {
// row, col이 경계 밖이거나 이미 방문했거나 이전 높이보다 낮은 경우
if (
row < 0 ||
row >= rows ||
col < 0 ||
col >= cols ||
heights[row][col] < prevHeight ||
visited.has(`${row},${col}`)
) {
return;
}

// 현재 위치 체크
visited.add(`${row},${col}`);

// 4방향 탐색
dfs(row + 1, col, heights[row][col], visited);
dfs(row - 1, col, heights[row][col], visited);
dfs(row, col + 1, heights[row][col], visited);
dfs(row, col - 1, heights[row][col], visited);
}

// 0,0에서부터 탐색 시작
for (let col = 0; col < cols; col++) {
dfs(0, col, heights[0][col], pacific);
}
for (let row = 0; row < rows; row++) {
dfs(row, 0, heights[row][0], pacific);
}

// rows-1, cols-1(pacific하고는 정반대 위치에서 시작)
for (let col = 0; col < cols; col++) {
dfs(rows - 1, col, heights[rows - 1][col], atlantic);
}
for (let row = 0; row < rows; row++) {
dfs(row, cols - 1, heights[row][cols - 1], atlantic);
}

const result: number[][] = [];
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
const pos = `${row},${col}`;
if (pacific.has(pos) && atlantic.has(pos)) {
result.push([row, col]);
}
}
}

return result;
}