-
Notifications
You must be signed in to change notification settings - Fork 126
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #402 from whewchews/main
[pepper] Week 03 Solutions
- Loading branch information
Showing
5 changed files
with
304 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* μμ΄λμ΄ | ||
* μΈ΅μ μ ν: 1 <= n <= 45 | ||
* 1 or 2 step λ§ μ¬λΌκ° μ μμ | ||
* 1 -> [1] | ||
* 2 -> [1,1] [2] | ||
* 3 -> [1,1,1] [2,1] [1,2] | ||
* 4 -> [1,1,1,1] [2,1,1] [1,2,1] [1,1,2] [2,2] | ||
* 5 -> [1,1,1,1,1] [2,1,1,1] [1,2,1,1] [1,1,2,1] [1,1,1,2] [2,2,1], [1,2,2], [2,1,2] | ||
* 6 -> [1,1,1,1,1,1] [2,1,1,1,1] [...] [1,1,1,1,2] [2,2,1,1], [2,1,2,1], [2,1,1,2] [1,1,2,2], [1,2,1,2], [1,2,2,1] | ||
=> (1:n, 2:0) nκ°μ§ (1:n-2, 2:1) / nκ°μ§ (1: n-4, 2: n/2) C(n, n/2) κ°μ§ | ||
*/ | ||
function climbStairs(n: number): number { | ||
// # Solution 1 | ||
|
||
// const stair = {1: 1, 2:2} | ||
// for(let i = 3; i<=n; i++){ | ||
// stair[i] = stair[i-1] + stair[i-2] | ||
// } | ||
// TC: O(N) | ||
// SC: O(N) | ||
|
||
// # Solution 2 | ||
|
||
// if(n < 3) return n | ||
// let curr = 2 // νμ¬ κ³λ¨μ μ€λ₯΄λ λ°©λ² μ | ||
// let prev = 1 // μ΄μ κ³λ¨μ μ€λ₯΄λ λ°©λ² μ | ||
|
||
// for(let i=0; i<n-2; i++){ | ||
// const next = prev + curr; | ||
// prev = curr; | ||
// curr = next; | ||
// } | ||
|
||
// return curr | ||
// TC: O(N) | ||
// SC: O(1) | ||
|
||
// # Solution 3: μ¬κ· | ||
const memo = { 1: 1, 2: 2 }; | ||
function calculateClimbingWay(n, memo) { | ||
if (n in memo) return memo[n]; | ||
|
||
if (n < 3) { | ||
return n; | ||
} | ||
memo[n] = | ||
calculateClimbingWay(n - 1, memo) + calculateClimbingWay(n - 2, memo); | ||
|
||
return memo[n]; | ||
} | ||
return calculateClimbingWay(n, memo); | ||
// TC: O(N) | ||
// SC: O(N) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
function coinChange(coins: number[], amount: number): number { | ||
/* # Solution 1: BFS | ||
* μ΅μ κ²½λ‘λ₯Ό μ°Ύλ λ¬Έμ => BFS | ||
* νμ¬κΉμ§ μ¬μ©ν λμ μ κ°μμ νμ¬κΉμ§ μ¬μ©ν λμ μ ν©μ queueμ λ£λλ€. | ||
* visited: μ€λ³΅ λ°©λ¬Έμ λ°©μ§νκΈ° μν set | ||
* λμ μ‘μ΄ amountμ κ°μμ§λ©΄ countλ₯Ό return | ||
* visitedμ λμ μ‘μ΄ μμΌλ©΄ continue | ||
* coinsλ₯Ό μννλ©΄μ λμ μ‘μ λμ μ λν κ°μ΄ amountλ³΄λ€ μμΌλ©΄ queueμ λ£λλ€. | ||
* queueκ° λΉλκΉμ§ λ°λ³΅ | ||
* νκ° λΉμ΄μκ³ amountλ₯Ό λ§λ€μ μμΌλ©΄ -1μ return | ||
*/ | ||
const queue = [[0, 0]]; // [number of coins, accumulated amount] | ||
const visited = new Set(); | ||
|
||
while (queue.length > 0) { | ||
const [count, total] = queue.shift(); | ||
if (total === amount) { | ||
return count; | ||
} | ||
if (visited.has(total)) { | ||
continue; | ||
} | ||
visited.add(total); | ||
for (const coin of coins) { | ||
if (total + coin <= amount) { | ||
queue.push([count + 1, total + coin]); | ||
} | ||
} | ||
} | ||
return -1; | ||
} | ||
// TC: κ° κΈμ‘(amount)λ§λ€ λμ (coins)μ μννλ―λ‘ O(N^2*M) N: amount, M: coins.length | ||
// SC: O(N) N: amount |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
function combinationSum(candidates: number[], target: number): number[][] { | ||
/* | ||
* ν©μ΄ targetμ΄ λλ candidates κ²½μ°μ μλ₯Ό λ¦¬ν΄ | ||
* cadidatesλ κ³ μ ν¨ | ||
* ν©μ΄ targetμ΄ λμ§ μλ κ²½μ°, λΉλ°°μ΄ λ¦¬ν΄ | ||
* cadidateμ μ€λ³΅ μ¬μ© κ°λ₯ | ||
* 2 <= candidates[i] <= 40 | ||
* => candidateμ΄ 1μΈ κ²½μ°λ μμ | ||
* candidatesμμ targetλ³΄λ€ κ°κ±°λ μμ κ°λ§ filterνκ³ μμ (targetλ³΄λ€ ν° κ°μ νλ³΄κ΅°μ΄ λ μ μμ) | ||
* | ||
* [2,3,6,7] / 7 | ||
* | ||
* [] | ||
* [2] / 5 | ||
* [2, 2] 3 => X | ||
* [2, 2, 2] 1 => X | ||
* [2, 2, 2, 2] -1 => X | ||
* [2, 2, 2, 3] -2 => X | ||
* [2, 2, 2, 6] -5 => X | ||
* [2, 2, 2, 7] -6 => X | ||
[2, 2, 3] 0 => O | ||
// ... | ||
[2, 3] 2 => X | ||
[2, 3, 2] 0 => O | ||
// ... | ||
[2, 6] -1 => X | ||
// ... | ||
* | ||
* νλμ© κ°μ μΆκ°νλ©΄μ λ°°μ΄μ μ΄ν©μ target κ°κ³Ό λΉκ΅νλ€ | ||
* sumμ΄ targetκ°λ³΄λ€ μμΌλ©΄ κ³μ λ€μ κ°μ μΆκ°ν΄μ€λ€ | ||
* sumμ΄ targetκ³Ό κ°μΌλ©΄ κ²°κ³Ό κ° result λ°°μ΄μ μΆκ°ν΄μ€λ€. | ||
* sumμ΄ targetλ³΄λ€ λμΌλ©΄ λ§μ§λ§μ μΆκ°ν κ°μ λΊλ€. | ||
* μ΄ κ³Όμ μ λ°λ³΅νλ©° λ°°μ΄μμ κ²°κ³Ό κ°μ μ°Ύλλ€. | ||
* | ||
*/ | ||
|
||
|
||
function backtrack(candidates: number[], start:number, total:number){ | ||
if(target === total){ | ||
result.push([...path]) | ||
return | ||
} | ||
|
||
if(target < total){ | ||
return | ||
} | ||
|
||
for(let i=start; i<=candidates.length-1; i++){ | ||
path.push(candidates[i]) | ||
backtrack(candidates, i,total + candidates[i]) | ||
path.pop() | ||
} | ||
} | ||
|
||
const result = [] | ||
const path = [] | ||
// TC: O(NlogN) | ||
// SC: O(N) | ||
const filteredCandidates = candidates.filter(candidate => candidate<=target).sort((a,b)=> a-b) | ||
backtrack(filteredCandidates, 0, 0) | ||
return result | ||
|
||
}; | ||
// TC: O(n^t) n = candidates.length, t = target ν¬κΈ° | ||
// SC: O(t) | ||
|
||
/* #Solution 2 : DP | ||
* candidatesμ κ°μ§κ³ target κ°μ λ§λ€ μ μλ λͺ¨λ μ‘°ν©μ 미리 μ°Ύμλλ€. | ||
*candidates [2,3,6,7] / target 7 λΌκ³ νμλ | ||
* 1) candidate = 2 | ||
* dp[2] = [[2]] | ||
* dp[4] = [[2,2]] | ||
* dp[6] = [[2,2,2]] | ||
* 2) candidate = 3 | ||
* dp[3] = [[3]] | ||
* dp[5] = [[2,3]] | ||
* dp[6] = [[2,2,2], [3,3]] | ||
* dp[7] = [[2,2,3]] | ||
* 3) candidate = 6 | ||
* dp[6] = [[[2,2,2], [3,3], [6]] | ||
* 4) candidate = 7 | ||
* dp[7] = [[2,2,3], [7]] | ||
* | ||
* => dp = [ | ||
* [ [] ] | ||
* [ [] ] | ||
* [ [2] ] | ||
* [[3]] | ||
* [[2,2]] | ||
* [[2,3,]] | ||
* [[2,2,2], [3,3], [6]] | ||
* [[2,2,3], [7]] | ||
* ] | ||
* ] | ||
* / | ||
|
||
|
||
|
||
// SC: O(t) t = target | ||
const dp = Array.from({ length: target + 1 }, () => []); | ||
dp[0] = [[]]; | ||
|
||
|
||
for (let candidate of candidates) { | ||
for (let i = candidate; i <= target; i++) { | ||
for (let combination of dp[i - candidate]) { | ||
dp[i].push([...combination, candidate]); | ||
} | ||
} | ||
} | ||
|
||
return dp[target]; | ||
} | ||
|
||
// TC: O(n * t * 2^n) n = candidates.length, t = target | ||
// SC: O((t*2^n) // μ΅μ μ κ²½μ° λͺ¨λ μ‘°ν©(2^n) μ μ₯ κ°λ₯ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* #Solution 1 | ||
* sum: μ 체 κ³±μ ꡬνλ€. | ||
* zeroCount: 0μ κ°μκ° λͺκ°μΈμ§ μΌλ€. | ||
* 1. μμ μ΄ 0μ΄λ©΄, | ||
* 1-1. μμ μ΄μΈμ 0μ΄ μλμ§ νμΈνκ³ μμΌλ©΄ 0μ return | ||
* 1-2. μμ μ΄μΈμ 0μ΄ μμΌλ©΄ μ 체 κ³±μ return | ||
* 2. μμ μ΄ 0μ΄ μλλ©΄ | ||
* 2-1. zeroCountκ° μλμ§ λ³΄κ³ μμΌλ©΄ 0μ return | ||
* 2-2. zeroκ° μμΌλ©΄ sum/selfλ₯Ό return | ||
* | ||
* κ·Έλ¬λ... λ¬Έμ μ λλκΈ° μ°μ°μλ₯Ό μ°λ©΄ μλλ€κ³ νμΌλ―λ‘ Solution 2λ‘ κ°μ. | ||
*/ | ||
function productExceptSelf(nums: number[]): number[] { | ||
// let zeroCount = 0; | ||
// const sum = nums.reduce((p, c) => { | ||
// if (c === 0) { | ||
// zeroCount += 1; | ||
// return p; | ||
// } | ||
// p = p * c; | ||
// return p; | ||
// }, 1); | ||
|
||
// const hasZero = zeroCount > 0; | ||
|
||
// if (zeroCount === nums.length) return Array(nums.length).fill(0); | ||
|
||
// return nums.map((n) => { | ||
// if (n === 0) { | ||
// // μμ μ΄μΈμ 0μ΄ μμλ | ||
// if (zeroCount - 1 > 0) { | ||
// return 0; | ||
// } | ||
|
||
// return sum; | ||
// } | ||
|
||
// if (hasZero) return 0; | ||
// return sum / n; | ||
// }); | ||
// TC: O(N) | ||
// SC: O(N) | ||
|
||
/* #Solution 2 | ||
* 1. prefix: μμ μ μ μΈν μκΈ° μΈλ±μ€ μκΉμ§μ κ³±μ μ μ₯νλ€. | ||
* 2. suffix: μμ μ μ μΈν μκΈ° λ€κΉμ§μ κ³±μ μ μ₯νλ€. | ||
* 3. answer[i] = prefix[i] * suffix[i] | ||
*/ | ||
const n = nums.length; | ||
|
||
const prefix = new Array(n).fill(1); | ||
const suffix = new Array(n).fill(1); | ||
|
||
for (let i = 1; i < n; i++) { | ||
prefix[i] = prefix[i - 1] * nums[i - 1]; | ||
} | ||
|
||
for (let i = n - 2; i >= 0; i--) { | ||
suffix[i] = suffix[i + 1] * nums[i + 1]; | ||
} | ||
|
||
const answer = []; | ||
for (let i = 0; i < n; i++) { | ||
answer[i] = prefix[i] * suffix[i]; | ||
} | ||
|
||
return answer; | ||
} | ||
// TC: O(N) | ||
// SC: O(N) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
* μμ΄λμ΄ | ||
* μ²μλΆν° λ°°μ΄μ μννλ©° [0,1] [0,2] [0,3] [0, ...], [1,2], [1,3], [1,...] ... [nums.length-2, nums.length-1] λ₯Ό λλ©΄μ λ μΈμμ ν©μ΄ targetμ΄ λλ μ§μ μ μ°Ύλλ€. | ||
* μμλλ‘ λλ©΄ μ΅μ μ κ²½μ° κ°μ₯ λ§μ§λ§ μ리κΉμ§ κ° μλ μλ€. | ||
* μ λ κ°μ΄ λμ§ λͺ»νλ, μ΅μ 쑰건μ μκ°ν΄λ³΄μ. | ||
* μ£Όμ1:λ²μκ° -10^9 <= nums[i] <= 10^9λ‘ μμκ°λ μμ | ||
* μ£Όμ2: μ λ ¬λ μμκ° μλ. | ||
* κ°μ Mapμ μ μ₯ν΄λκ³ {value: index}, Mapμ μμ κ³Ό λνμλ targetμ΄ λμ€λ valueκ° μλμ§ νμΈ | ||
*/ | ||
function twoSum(nums: number[], target: number): number[] { | ||
// SC: O(N) | ||
const dict = new Map(); | ||
|
||
// TC: O(N) | ||
for (let i = 0; i <= nums.length - 1; i++) { | ||
const curr = nums[i]; | ||
const pairValue = target - curr; | ||
if (dict.has(pairValue)) { | ||
return [dict.get(pairValue), i]; | ||
} | ||
|
||
dict.set(curr, i); | ||
} | ||
} | ||
|
||
// TC: O(N) | ||
// SC: O(N) |