Skip to content

Commit b3d7d16

Browse files
authored
Merge pull request #1675 from soobing/week1
[soobing] WEEK01 Solution
2 parents 81f42e0 + 643d90f commit b3d7d16

File tree

5 files changed

+251
-0
lines changed

5 files changed

+251
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* ๋ฌธ์ œ ์œ ํ˜•
3+
* - Array
4+
*
5+
* ๋ฌธ์ œ ์„ค๋ช…
6+
* - ์ค‘๋ณต๋œ ์ˆ˜๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ true, ์—†์œผ๋ฉด false ๋ฐ˜ํ™˜
7+
*
8+
* ์•„์ด๋””์–ด
9+
* - ์ „์ฒด์ ์œผ๋กœ ์ˆœํšŒํ•˜๋ฉด์„œ ์ค‘๋ณต๋œ ์ˆ˜๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ
10+
*
11+
*/
12+
function containsDuplicate(nums: number[]): boolean {
13+
const set = new Set<number>();
14+
for (let i = 0; i < nums.length; i++) {
15+
if (set.has(nums[i])) return true;
16+
17+
set.add(nums[i]);
18+
}
19+
return false;
20+
}

โ€Žhouse-robber/soobing2.tsโ€Ž

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* ๋ฌธ์ œ ์œ ํ˜•: DP
3+
*
4+
* ๋ฌธ์ œ ์„ค๋ช…
5+
* - ๋ฐ”๋กœ ์˜†์ง‘์„ ํ•œ๋ฒˆ์— ํ„ธ ์ˆ˜ ์—†์„๋•Œ, ์ตœ๋Œ€๋กœ ํ„ธ ์ˆ˜ ์žˆ๋Š” ๋ˆ์„ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ
6+
* - ํ•จ์ •์€, ํ™€์ˆ˜์˜ ํ•ฉ vs ์ง์ˆ˜์˜ ํ•ฉ๋งŒ ๋น„๊ตํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค. 2๊ฐœ ์ดˆ๊ณผํ•ด์„œ ํ„ธ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Œ (ex. [2, 1, 1, 2])
7+
*
8+
* ์•„์ด๋””์–ด
9+
* - DP ๋ฌธ์ œ ๋‹ต๊ฒŒ Top-down, Bottom-up ๋‘ ๊ฐœ ๋‹ค ํ’€ ์ˆ˜ ์žˆ์Œ
10+
*/
11+
12+
function robBottomUp(nums: number[]): number {
13+
const n = nums.length;
14+
const dp = Array(n).fill(0);
15+
16+
if (n === 1) return nums[0];
17+
if (n === 2) return Math.max(nums[0], nums[1]);
18+
19+
dp[0] = nums[0];
20+
dp[1] = Math.max(nums[0], nums[1]);
21+
22+
for (let i = 2; i < n; i++) {
23+
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
24+
}
25+
26+
return dp[n - 1];
27+
}
28+
29+
function robTopDown(nums: number[]): number {
30+
const n = nums.length;
31+
const memo = new Map<number, number>();
32+
33+
const dp = (i: number) => {
34+
if (i < 0) return 0;
35+
if (memo.has(i)) return memo.get(i);
36+
37+
const res = Math.max(dp(i - 1)!, dp(i - 2)! + nums[i]);
38+
memo.set(i, res);
39+
return res;
40+
};
41+
return dp(n - 1)!;
42+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* ๋ฌธ์ œ ์œ ํ˜•: ๊ทธ๋ž˜ํ”„(Union Find)
3+
*
4+
* ๋ฌธ์ œ ์„ค๋ช…
5+
* - ์ฃผ์–ด์ง„ ๋ฐฐ์—ด์—์„œ ๊ฐ€์žฅ ๊ธด ์—ฐ์†๋œ ์ˆ˜์—ด์˜ ๊ธธ์ด๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ
6+
*
7+
* ์•„์ด๋””์–ด
8+
* 1) ์ค‘๋ณต๋œ ์ˆ˜ ์ œ๊ฑฐ ํ›„ ์ˆœํšŒํ•˜๋ฉฐ ๊ฐ’์ด 1์ฐจ์ด ๋‚˜๋Š” ํ•ญ๋ชฉ๋ผ๋ฆฌ ํ•ฉ์ง‘ํ•ฉ ๋งŒ๋“ค๊ธฐ
9+
*
10+
* ๋ฏธ์…˜
11+
* - ๋” ๋น ๋ฅธ ํ’€์ด: HashSet ๊ธฐ๋ฐ˜ Greedy๋กœ ํ’€์–ด๋ณด๊ธฐ.
12+
*
13+
*/
14+
class UnionFind {
15+
parent: Map<number, number> = new Map();
16+
size: Map<number, number> = new Map();
17+
18+
constructor(nums: number[]) {
19+
for (const num of nums) {
20+
this.parent.set(num, num);
21+
this.size.set(num, 1);
22+
}
23+
}
24+
25+
find(x: number): number {
26+
if (this.parent.get(x) !== x) {
27+
this.parent.set(x, this.find(this.parent.get(x)!));
28+
}
29+
30+
return this.parent.get(x)!;
31+
}
32+
33+
union(x: number, y: number): void {
34+
const rootX = this.find(x);
35+
const rootY = this.find(y);
36+
37+
if (rootX === rootY) return;
38+
39+
const sizeX = this.size.get(rootX);
40+
const sizeY = this.size.get(rootY);
41+
if (sizeX < sizeY) {
42+
this.parent.set(rootX, rootY);
43+
this.size.set(rootY, sizeX + sizeY);
44+
} else {
45+
this.parent.set(rootY, rootX);
46+
this.size.set(rootX, sizeX + sizeY);
47+
}
48+
}
49+
50+
getMaxSize(): number {
51+
let max = 0;
52+
for (const size of this.size.values()) {
53+
max = Math.max(max, size);
54+
}
55+
return max;
56+
}
57+
}
58+
function longestConsecutive(nums: number[]): number {
59+
if (nums.length === 0) return 0;
60+
61+
const uniqueNums = Array.from(new Set(nums));
62+
const uf = new UnionFind(uniqueNums);
63+
64+
for (const num of uniqueNums) {
65+
if (uf.parent.has(num + 1)) {
66+
uf.union(num, num + 1);
67+
}
68+
}
69+
70+
return uf.getMaxSize();
71+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/**
2+
* ๋ฌธ์ œ ์œ ํ˜•: Heap
3+
*
4+
* ๋ฌธ์ œ ์„ค๋ช…
5+
* - ๊ฐ€์žฅ ๋นˆ๋„์ˆ˜๊ฐ€ ๋งŽ์€ K๊ฐœ Element ์ถ”์ถœ
6+
*
7+
* ์•„์ด๋””์–ด
8+
* 1) ๋นˆ๋„์ˆ˜ ๊ณ„์‚ฐํ•˜์—ฌ index์™€ ํ•จ๊ป˜ Map์— ์ €์žฅ, ๋นˆ๋„์ˆ˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ MinHeap ๊ตฌ์„ฑ
9+
* 2) ๋นˆ๋„์ˆ˜ Map์„ ์ˆœํšŒํ•˜๋ฉด์„œ MinHeap์— ์ถ”๊ฐ€ + MinHeap์˜ ํฌ๊ธฐ๊ฐ€ K๋ฅผ ์ดˆ๊ณผํ•˜๋ฉด ์ตœ์†Œ๊ฐ’ ์ œ๊ฑฐ (๋ฏธ๋ฆฌ๋ฏธ๋ฆฌ ๋นˆ๋„์ˆ˜๊ฐ€ ๋งŽ์€ K๊ฐœ Element๋ฅผ ๋งŒ๋“ค์–ด๋‚˜๊ฐ€๋Š” ํ˜•์‹)
10+
* 3) MinHeap์— ๋‚จ์•„์žˆ๋Š” Element๋“ค์˜ index๋ฅผ ๋ฐ˜ํ™˜
11+
*
12+
* ์‹œ๊ฐ„ ๋ณต์žก๋„: O(NlogK)
13+
* ๊ณต๊ฐ„ ๋ณต์žก๋„: O(N)
14+
*/
15+
class MinHeap {
16+
heap: [number, number][] = [];
17+
18+
insert(item: [number, number]) {
19+
this.heap.push(item);
20+
this.bubbleUp();
21+
}
22+
23+
private bubbleUp() {
24+
let index = this.heap.length - 1;
25+
while (index > 0) {
26+
const parentIndex = Math.floor((index - 1) / 2);
27+
if (this.heap[index][0] >= this.heap[parentIndex][0]) break;
28+
[this.heap[index], this.heap[parentIndex]] = [
29+
this.heap[parentIndex],
30+
this.heap[index],
31+
];
32+
index = parentIndex;
33+
}
34+
}
35+
36+
extractMin(): [number, number] | undefined {
37+
if (this.heap.length === 0) return undefined;
38+
const min = this.heap[0];
39+
const end = this.heap.pop();
40+
if (this.heap.length > 0 && end !== undefined) {
41+
this.heap[0] = end;
42+
this.sinkDown(0);
43+
}
44+
return min;
45+
}
46+
47+
private sinkDown(index: number) {
48+
const length = this.heap.length;
49+
while (true) {
50+
let left = 2 * index + 1;
51+
let right = 2 * index + 2;
52+
let smallest = index;
53+
54+
if (left < length && this.heap[left][0] < this.heap[smallest][0]) {
55+
smallest = left;
56+
}
57+
if (right < length && this.heap[right][0] < this.heap[smallest][0]) {
58+
smallest = right;
59+
}
60+
if (index === smallest) break;
61+
62+
[this.heap[index], this.heap[smallest]] = [
63+
this.heap[smallest],
64+
this.heap[index],
65+
];
66+
index = smallest;
67+
}
68+
}
69+
70+
peek(): [number, number] | undefined {
71+
return this.heap[0];
72+
}
73+
74+
size(): number {
75+
return this.heap.length;
76+
}
77+
}
78+
function topKFrequent(nums: number[], k: number): number[] {
79+
const freqMap = new Map<number, number>();
80+
for (const num of nums) {
81+
freqMap.set(num, (freqMap.get(num) ?? 0) + 1);
82+
}
83+
84+
const minHeap = new MinHeap();
85+
for (const [num, count] of freqMap.entries()) {
86+
minHeap.insert([count, num]);
87+
if (minHeap.size() > k) {
88+
minHeap.extractMin();
89+
}
90+
}
91+
92+
return minHeap.heap.map(([_, num]) => num);
93+
}

โ€Žtwo-sum/soobing2.tsโ€Ž

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* ๋ฌธ์ œ ์œ ํ˜•
3+
* - Array
4+
*
5+
* ๋ฌธ์ œ ์„ค๋ช…
6+
* - ์ฃผ์–ด์ง„ ๋ฐฐ์—ด์—์„œ ๋‘ ์ˆ˜๋ฅผ ๋”ํ•ด์„œ target ๊ฐ’์ด ๋˜๋Š” ์ธ๋ฑ์Šค๋ฅผ ๋ฐ˜ํ™˜
7+
*
8+
* ์•„์ด๋””์–ด
9+
* - ์ˆœํšŒํ•˜๋ฉด์„œ map์„ ๋จผ์ € ๋งŒ๋“ค์–ด๋‘๊ณ , ๋‹ค์‹œ ์ˆœํšŒํ•˜๋ฉด์„œ target-nums[i] ๊ฐ’์ด ์žˆ๋Š”์ง€ ํ™•์ธ
10+
*/
11+
function twoSum(nums: number[], target: number): number[] {
12+
const map = new Map();
13+
for (let i = 0; i < nums.length; i++) {
14+
map.set(nums[i], i);
15+
}
16+
17+
for (let i = 0; i < nums.length; i++) {
18+
const index = map.get(target - nums[i]);
19+
if (i === index || index === undefined) continue;
20+
21+
return [i, index];
22+
}
23+
24+
return [];
25+
}

0 commit comments

Comments
ย (0)