Skip to content

[uraflower] Week 09 Solutions #1522

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 5 commits into from
May 30, 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
50 changes: 50 additions & 0 deletions linked-list-cycle/uraflower.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/

/**
* 연결 리스트의 사이클 여부를 반환하는 함수
* 시간복잡도: O(n)
* 공간복잡도: O(1)
* @param {ListNode} head
* @return {boolean}
*/
const hasCycle = function(head) {
let node = head;

while (node?.next) {
if (node.val === null) {
return true;
}
node.val = null;
node = node.next;
}

return false;
};

// 거북이와 토끼 알고리즘
// 시간복잡도: O(n)
// 공간복잡도: O(1)
const hasCycle = function(head) {
let slow = head; // 한 번에 한 노드씩
let fast = head; // 한 번에 두 노드씩

while (fast?.next) {
slow = slow.next;
fast = fast.next.next;

// 한 번에 두 노드씩 가는 fast가
// 자신보다 느린 slow랑 같은 경우가 생긴다면
// 사이클이 있다는 뜻
if (slow === fast) {
return true;
}
}

return false;
};
23 changes: 23 additions & 0 deletions maximum-product-subarray/uraflower.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* 주어진 배열에서 가장 큰 부분 배열의 곱을 반환하는 함수
* @param {number[]} nums
* @return {number}
*/
const maxProduct = function (nums) {
let min = nums[0];
let max = nums[0];
let result = nums[0]; // 현재까지 가장 큰 부분 배열 곱을 저장

for (let i = 1; i < nums.length; i++) {
let tempMin = Math.min(nums[i], min * nums[i], max * nums[i]);
let tempMax = Math.max(nums[i], min * nums[i], max * nums[i]);
min = tempMin;
max = tempMax;
result = Math.max(result, max);
}

return result;
}

// 시간복잡도: O(n)
// 공간복잡도: O(1)
52 changes: 52 additions & 0 deletions minimum-window-substring/uraflower.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* @param {string} s
* @param {string} t
* @return {string}
*/
const minWindow = function (s, t) {
const counter = Array.from(t).reduce((obj, char) => {
obj[char] = (obj[char] || 0) + 1;
return obj;
}, {});

let lettersToSatisfy = Object.keys(counter).length;
let minStart = 0;
let minEnd = Infinity;

let start = 0;
for (let end = 0; end < s.length; end++) {
// s[end]가 t에 포함된 문자인 경우
if (s[end] in counter) {
counter[s[end]]--;

// 해당 문자가 범위 안에 모두 포함된 경우
if (counter[s[end]] === 0) {
lettersToSatisfy--;
}
}

// 현재 범위에 t 내 모든 문자가 포함된 경우
while (lettersToSatisfy === 0) {
// 더 작은 범위로 정답 갱신
if (end - start < minEnd - minStart) {
minStart = start;
minEnd = end;
}

// start 늘리기
if (s[start] in counter) {
counter[s[start]]++;
if (counter[s[start]] > 0) {
lettersToSatisfy++;
}
}

start++;
}
}

return minEnd === Infinity ? '' : s.slice(minStart, minEnd + 1);
};

// 시간복잡도: O(m) (m: s.length)
// 공간복잡도: O(1)
70 changes: 70 additions & 0 deletions pacific-atlantic-water-flow/uraflower.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* @param {number[][]} heights
* @return {number[][]}
*/
const pacificAtlantic = function (heights) {
// 각 cell에서 시작해서 바다로 뻗어나가는 것 말고
// 바다에서 시작해서 각 cell이 바다로 흘러올 수 있는지 확인한 후
// 두 바다에 모두 흘러갈 수 있는 cell만 filter

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

// 각 바다에 도달 가능한지 여부를 담는 visited를 만듦
const pacific = Array.from({ length: rows }, () => Array(cols).fill(false));
const atlantic = Array.from({ length: rows }, () => Array(cols).fill(false));

const direction = [[0, 1], [0, -1], [1, 0], [-1, 0]];

// 순회
function bfs(r, c, visited) {
visited[r][c] = true;

const queue = [[r, c]];

while (queue.length) {
const [r, c] = queue.shift();

for (const [dr, dc] of direction) {
const nr = r + dr;
const nc = c + dc;

// 나보다 height가 크고, 방문한 적 없으면, 큐에 담기
if (0 <= nr && nr < rows && 0 <= nc && nc < cols
&& !visited[nr][nc]
&& heights[nr][nc] >= heights[r][c]
) {
queue.push([nr, nc]);
visited[nr][nc] = true;
}
}
}
}

// 바다에서 시작해서 거꾸로 탐색
for (let r = 0; r < rows; r++) {
bfs(r, 0, pacific); // left
bfs(r, cols - 1, atlantic); // right
}

for (let c = 0; c < cols; c++) {
bfs(0, c, pacific); // top
bfs(rows - 1, c, atlantic); // bottom
}

// 태평양, 대서양으로 모두 flow할 수 있는 cell 찾기
const result = [];

for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
if (pacific[r][c] && atlantic[r][c]) {
result.push([r, c]);
}
}
}

return result;
};

// 시간복잡도: O(m*n)
// 공간복잡도: O(m*n)
16 changes: 16 additions & 0 deletions sum-of-two-integers/uraflower.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* +, - 연산자를 사용하지 않고 a, b를 더하는 함수
* @param {number} a
* @param {number} b
* @return {number}
*/
const getSum = function (a, b) {
while (b !== 0) {
[a, b] = [a ^ b, (a & b) << 1]
}

return a;
};

// 시간복잡도: O(1)
// 공간복잡도: O(1)