Skip to content

Commit 5726dc5

Browse files
authored
Merge pull request #1632 from uraflower/main
[uraflower] Week 14 Solutions
2 parents a4a91b3 + 5fddc45 commit 5726dc5

File tree

5 files changed

+237
-0
lines changed

5 files changed

+237
-0
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* Definition for a binary tree node.
3+
* function TreeNode(val, left, right) {
4+
* this.val = (val===undefined ? 0 : val)
5+
* this.left = (left===undefined ? null : left)
6+
* this.right = (right===undefined ? null : right)
7+
* }
8+
*/
9+
/**
10+
* @param {TreeNode} root
11+
* @return {number[][]}
12+
*/
13+
const levelOrder = function(root) {
14+
if (!root) return [];
15+
16+
const queue = [[root]];
17+
const result = [];
18+
19+
while (queue.length) {
20+
const curNodes = queue.shift();
21+
const newNodes = []; // 나중에 queue에 넣을 배열로 child node들이 들어감
22+
const newResult = []; // 나중에 result에 넣을 배열로 node.val이 들어감
23+
24+
curNodes.forEach((node) => {
25+
newResult.push(node.val);
26+
if (node.left) newNodes.push(node.left);
27+
if (node.right) newNodes.push(node.right);
28+
});
29+
30+
if (newNodes.length) queue.push(newNodes);
31+
result.push(newResult)
32+
}
33+
34+
return result;
35+
};
36+
37+
// 시간복잡도: O(n)
38+
// 공간복잡도: O(n)
39+
40+
/*
41+
위 풀이는 배열을 4개 사용하고 있음
42+
아래 풀이는 배열을 줄인 방식
43+
*/
44+
const levelOrder = function(root) {
45+
if (!root) return [];
46+
47+
const queue = [root];
48+
const result = [];
49+
50+
while (queue.length) {
51+
const level = [];
52+
53+
// queue에 있는 노드 다 꺼내기
54+
for (let i = 0; i < queue.length; i++) {
55+
const node = queue.shift();
56+
level.push(node.val);
57+
58+
if (node.left) queue.push(node.left);
59+
if (node.right) queue.push(node.right);
60+
}
61+
62+
result.push(level);
63+
}
64+
65+
return result;
66+
};

counting-bits/uraflower.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* 두 번째 풀이
3+
* 시간복잡도: O(n)
4+
* 공간복잡도: O(n)
5+
* @param {number} n
6+
* @return {number[]}
7+
*/
8+
const countBits = function (n) {
9+
const arr = [0];
10+
11+
for (let i = 1; i < n + 1; i++) {
12+
arr[i] = arr[i >> 1] + (i & 1);
13+
// i >> 1: 최하위 비트를 제외한 값. 이걸 이용해서 이전 인덱스 사용(dp)
14+
// i // 2 (2로 나눈 몫)와 같음.
15+
// i & 1: 최하위 비트 (1 또는 0)
16+
}
17+
18+
return arr;
19+
};
20+
21+
/**
22+
* 첫 번째 풀이
23+
* 시간복잡도: O(n * log n)
24+
* 공간복잡도: O(n)
25+
* @param {number} n
26+
* @return {number[]}
27+
*/
28+
const countBits = function (n) {
29+
const arr = [];
30+
31+
for (let i = 0; i < n + 1; i++) {
32+
const bin = i.toString(2); // O(log n)
33+
34+
let num = 0;
35+
36+
// O(log n)
37+
for (let char of bin) {
38+
if (char === '1') num++;
39+
}
40+
41+
arr.push(num);
42+
}
43+
44+
return arr;
45+
};

house-robber-ii/uraflower.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// 최대 금액은 ...
2+
// nums[0]을 터는 경우: rob(nums[2] ~ nums[last - 1]) + nums[0]
3+
// nums[0]을 안 터는 경우: rob(nums[1] ~ nums[last])
4+
// 따라서 nums[0]을 털지 말지 여부를 기준으로 나누어 계산
5+
6+
/**
7+
* @param {number[]} nums
8+
* @return {number}
9+
*/
10+
const rob = function (nums) {
11+
if (nums.length === 1) return nums[0];
12+
13+
const dp1 = [nums[0]]; // 첫 집을 터는 경우 최대 금액
14+
const dp2 = [0]; // 첫 집을 안 터는 경우 최대 금액
15+
16+
for (let i = 1; i < nums.length; i++) {
17+
dp1[i] = Math.max(dp1[i - 1], (dp1[i - 2] || 0) + nums[i]);
18+
dp2[i] = Math.max(dp2[i - 1], (dp2[i - 2] || 0) + nums[i]);
19+
}
20+
21+
return Math.max(dp1[dp1.length - 2], dp2[dp2.length - 1]);
22+
}
23+
24+
// 시간복잡도: O(n)
25+
// 공간복잡도: O(n)

meeting-rooms-ii/uraflower.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @param {number[][]} intervals
3+
* @return {number}
4+
*/
5+
const minMeetingRooms = function(intervals) {
6+
const starts = intervals.map(i => i[0]).sort((a, b) => a - b);
7+
const ends = intervals.map(i => i[1]).sort((a, b) => a - b);
8+
9+
let rooms = 0;
10+
let endIdx = 0;
11+
12+
for (let i = 0; i < starts.length; i++) {
13+
if (starts[i] < ends[endIdx]) {
14+
rooms++; // 새로운 방이 필요
15+
} else {
16+
endIdx++; // 기존 방 재사용 가능
17+
}
18+
}
19+
20+
return rooms;
21+
};
22+
23+
// 시간복잡도: O(n * log n) (정렬)
24+
// 공간복잡도: O(n)

word-search-ii/uraflower.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// 모든 word에 대해
2+
// board를 순회하면서
3+
// word의 첫 글자가 board의 현 위치 문자와 같다면 dfs
4+
// 이렇게 풀 경우 O(W * m * n * 4^L)만큼 시간이 걸림 (W: words.length, L: word.length)
5+
6+
// 그래서 모든 word를 트라이로 저장하고
7+
// board를 한 번만 순회하는 방법을 사용
8+
9+
const buildTrie = (words) => {
10+
const root = {};
11+
12+
for (const word of words) {
13+
let node = root;
14+
for (const char of word) {
15+
if (!node[char]) node[char] = {};
16+
node = node[char];
17+
}
18+
node.word = word;
19+
}
20+
21+
return root;
22+
}
23+
24+
/**
25+
* @param {character[][]} board
26+
* @param {string[]} words
27+
* @return {string[]}
28+
*/
29+
const findWords = function (board, words) {
30+
const m = board.length;
31+
const n = board[0].length;
32+
const trie = buildTrie(words);
33+
const result = [];
34+
35+
const dr = [0, 0, 1, -1];
36+
const dc = [1, -1, 0, 0];
37+
const visited = Array.from({ length: m }).map(() => Array.from({ length: n }).fill(false));
38+
39+
const dfs = (r, c, node, path) => {
40+
const char = board[r][c];
41+
const nextNode = node[char];
42+
if (!nextNode) return;
43+
44+
if (nextNode.word) {
45+
result.push(nextNode.word);
46+
nextNode.word = null;
47+
}
48+
49+
visited[r][c] = true;
50+
51+
for (let i = 0; i < 4; i++) {
52+
const nr = r + dr[i];
53+
const nc = c + dc[i];
54+
55+
if (0 <= nr && nr < m && 0 <= nc && nc < n && !visited[nr][nc]) {
56+
dfs(nr, nc, nextNode, path + board[nr][nc]);
57+
}
58+
}
59+
60+
visited[r][c] = false;
61+
}
62+
63+
for (let i = 0; i < m; i++) {
64+
for (let j = 0; j < n; j++) {
65+
dfs(i, j, trie, '');
66+
}
67+
}
68+
69+
return result;
70+
};
71+
72+
// 시간복잡도: O(m * n * 4^L) (L: word.length)
73+
// 공간복잡도: O(W * L + m * n)
74+
// - trie: O(W * L) (W: words.length)
75+
// - vistied: O(m * n)
76+
// - 재귀스택: O(L)
77+
// - result: O(K * L) (K: 찾은 단어 수)

0 commit comments

Comments
 (0)