Skip to content

Commit a9dfecc

Browse files
authored
Merge pull request #2087 from smosco/main
[smosco] WEEK 03 solutions
2 parents 4c9b0d0 + 5118c0d commit a9dfecc

File tree

5 files changed

+196
-0
lines changed

5 files changed

+196
-0
lines changed

โ€Žcombination-sum/smosco.jsโ€Ž

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* Combination Sum
3+
*
4+
* ํ•ต์‹ฌ ์•„์ด๋””์–ด:
5+
* - DFS + ๋ฐฑํŠธ๋ž˜ํ‚น์œผ๋กœ ๋ชจ๋“  ์กฐํ•ฉ ํƒ์ƒ‰
6+
* - ๊ฐ™์€ ์ˆซ์ž๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
7+
* - start ์ธ๋ฑ์Šค๋กœ ์ค‘๋ณต ์กฐํ•ฉ ๋ฐฉ์ง€ ([2,3]๊ณผ [3,2] ๊ฐ™์€ ๊ฒƒ)
8+
*
9+
* ์‹œ๊ฐ„ ๋ณต์žก๋„: O(N^(T/M)) - N: ํ›„๋ณด ๊ฐœ์ˆ˜, T: ํƒ€๊ฒŸ, M: ์ตœ์†Œ๊ฐ’
10+
* ๊ณต๊ฐ„ ๋ณต์žก๋„: O(T/M) - ์žฌ๊ท€ ๊นŠ์ด
11+
*/
12+
13+
const combinationSum = (candidates, target) => {
14+
const result = [];
15+
16+
const dfs = (remain, start, path) => {
17+
// Base case: ํƒ€๊ฒŸ ๋‹ฌ์„ฑ
18+
if (remain === 0) {
19+
result.push([...path]); // ํ˜„์žฌ ๊ฒฝ๋กœ ์ €์žฅ
20+
return;
21+
}
22+
23+
// Base case: ํƒ€๊ฒŸ ์ดˆ๊ณผ (pruning)
24+
if (remain < 0) return;
25+
26+
// ๋ชจ๋“  ํ›„๋ณด ํƒ์ƒ‰
27+
for (let i = start; i < candidates.length; i++) {
28+
// ๊ฐ€์ง€์น˜๊ธฐ: ๋‚จ์€ ๊ฐ’๋ณด๋‹ค ํฌ๋ฉด ์Šคํ‚ต
29+
if (candidates[i] > remain) continue;
30+
31+
// ์„ ํƒ
32+
path.push(candidates[i]);
33+
34+
// ํƒ์ƒ‰ (i๋ถ€ํ„ฐ ์‹œ์ž‘ - ๊ฐ™์€ ์ˆซ์ž ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ)
35+
dfs(remain - candidates[i], i, path);
36+
37+
// ๋˜๋Œ๋ฆฌ๊ธฐ (๋ฐฑํŠธ๋ž˜ํ‚น)
38+
path.pop();
39+
}
40+
};
41+
42+
dfs(target, 0, []);
43+
return result;
44+
};

โ€Ždecode-ways/smosco.jsโ€Ž

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Decode Ways
3+
*
4+
* ํ•ต์‹ฌ ์•„์ด๋””์–ด:
5+
* - ์ˆซ์ž ๋ฌธ์ž์—ด์„ 1-26(A-Z)๋กœ ๋””์ฝ”๋”ฉํ•˜๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ
6+
* - dp[i] = ์•ž์—์„œ๋ถ€ํ„ฐ i๊ฐœ์˜ ๋ฌธ์ž๋ฅผ ๋””์ฝ”๋”ฉํ•˜๋Š” ๋ฐฉ๋ฒ• ์ˆ˜
7+
* - ๊ฐ ์œ„์น˜์—์„œ 2๊ฐ€์ง€ ์„ ํƒ ๊ฐ€๋Šฅ:
8+
* 1) ํ•œ ์ž๋ฆฌ ์ˆซ์ž๋กœ ํ•ด์„ (1-9)
9+
* 2) ๋‘ ์ž๋ฆฌ ์ˆซ์ž๋กœ ํ•ด์„ (10-26)
10+
*
11+
* ์‹œ๊ฐ„ ๋ณต์žก๋„: O(n) - ๋ฌธ์ž์—ด์„ ํ•œ ๋ฒˆ๋งŒ ์ˆœํšŒ
12+
* ๊ณต๊ฐ„ ๋ณต์žก๋„: O(n) - dp ๋ฐฐ์—ด ์‚ฌ์šฉ
13+
*/
14+
15+
function numDecodings(s) {
16+
// ์˜ˆ์™ธ ์ฒ˜๋ฆฌ: ๋นˆ ๋ฌธ์ž์—ด์ด๊ฑฐ๋‚˜ '0'์œผ๋กœ ์‹œ์ž‘ํ•˜๋ฉด ๋ถˆ๊ฐ€๋Šฅ
17+
if (!s || s[0] === '0') return 0;
18+
19+
const n = s.length;
20+
const dp = new Array(n + 1).fill(0);
21+
22+
// ์ดˆ๊ธฐ๊ฐ’ ์„ค์ •
23+
dp[0] = 1; // ๋นˆ ๋ฌธ์ž์—ด (base case)
24+
dp[1] = 1; // ์ฒซ ๋ฒˆ์งธ ๋ฌธ์ž (์ด๋ฏธ '0' ์ฒดํฌ ์™„๋ฃŒ)
25+
26+
// i๋ฒˆ์งธ ์œ„์น˜๊นŒ์ง€์˜ ๋””์ฝ”๋”ฉ ๋ฐฉ๋ฒ• ์ˆ˜ ๊ณ„์‚ฐ
27+
for (let i = 2; i <= n; i++) {
28+
// 1) ํ•œ ์ž๋ฆฌ ์ˆซ์ž๋กœ ํ•ด์„ (1~9๋งŒ ๊ฐ€๋Šฅ, 0์€ ๋‹จ๋… ๋ถˆ๊ฐ€)
29+
const oneDigit = s[i - 1];
30+
if (oneDigit !== '0') {
31+
dp[i] += dp[i - 1]; // ์ด์ „๊นŒ์ง€์˜ ๋ชจ๋“  ๋ฐฉ๋ฒ•์— ํ˜„์žฌ ์ˆซ์ž ์ถ”๊ฐ€
32+
}
33+
34+
// 2) ๋‘ ์ž๋ฆฌ ์ˆซ์ž๋กœ ํ•ด์„ (10~26๋งŒ ๊ฐ€๋Šฅ)
35+
const twoDigits = s[i - 2] + s[i - 1];
36+
const twoDigitsNum = parseInt(twoDigits);
37+
if (twoDigitsNum >= 10 && twoDigitsNum <= 26) {
38+
dp[i] += dp[i - 2]; // i-2๊นŒ์ง€์˜ ๋ชจ๋“  ๋ฐฉ๋ฒ•์— ๋‘ ์ž๋ฆฌ ์ˆซ์ž ์ถ”๊ฐ€
39+
}
40+
}
41+
42+
return dp[n];
43+
}

โ€Žmaximum-subarray/smosco.jsโ€Ž

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* Maximum Subarray - ๋ธŒ๋ฃจํŠธํฌ์Šค (์™„์ „ํƒ์ƒ‰)
3+
*
4+
* ํ•ต์‹ฌ ์•„์ด๋””์–ด:
5+
* - ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ์—ฐ์† ๋ถ€๋ถ„ ๋ฐฐ์—ด์˜ ํ•ฉ์„ ๊ณ„์‚ฐํ•˜์—ฌ ์ตœ๋Œ“๊ฐ’ ์ฐพ๊ธฐ
6+
* - i๋ฒˆ์งธ๋ถ€ํ„ฐ j๋ฒˆ์งธ๊นŒ์ง€์˜ ํ•ฉ์„ ๋ˆ„์ ํ•˜๋ฉด์„œ ๊ณ„์‚ฐ
7+
*
8+
* ์‹œ๊ฐ„ ๋ณต์žก๋„: O(nยฒ) - ์ด์ค‘ ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ๋ชจ๋“  ๊ตฌ๊ฐ„ ํƒ์ƒ‰
9+
* ๊ณต๊ฐ„ ๋ณต์žก๋„: O(1) - ๋ณ€์ˆ˜ ๋ช‡ ๊ฐœ๋งŒ ์‚ฌ์šฉ
10+
*/
11+
const maxSubArray = (nums) => {
12+
const n = nums.length;
13+
let maxSoFar = nums[0];
14+
15+
for (let i = 0; i < n; i++) {
16+
let currentSum = 0;
17+
for (let j = i; j < n; j++) {
18+
currentSum += nums[j]; // i๋ถ€ํ„ฐ j๊นŒ์ง€์˜ ๋ˆ„์  ํ•ฉ
19+
maxSoFar = Math.max(maxSoFar, currentSum);
20+
}
21+
}
22+
23+
return maxSoFar;
24+
};
25+
26+
/**
27+
* Maximum Subarray - Kadane's Algorithm
28+
*
29+
* ํ•ต์‹ฌ ์•„์ด๋””์–ด:
30+
* - ๊ฐ ์œ„์น˜์—์„œ "ํ˜„์žฌ ์ˆซ์ž๋งŒ์œผ๋กœ ์ƒˆ๋กœ ์‹œ์ž‘ vs ์ด์ „ ํ•ฉ์— ํ˜„์žฌ ์ˆซ์ž ์ถ”๊ฐ€" ์ค‘ ๋” ํฐ ๊ฐ’ ์„ ํƒ
31+
* - currentMax = max(ํ˜„์žฌ ์ˆซ์ž, ์ง€๊ธˆ๊นŒ์ง€ ํ•ฉ + ํ˜„์žฌ ์ˆซ์ž)
32+
* - ์ฆ‰, ์ด์ „๊นŒ์ง€์˜ ํ•ฉ์ด ํ˜„์žฌ์— ๋„์›€์ด ์•ˆ ๋˜๋ฉด ๋ฒ„๋ฆฌ๊ณ  ์ƒˆ๋กœ ์‹œ์ž‘
33+
*
34+
* ์‹œ๊ฐ„ ๋ณต์žก๋„: O(n) - ๋ฐฐ์—ด์„ ํ•œ ๋ฒˆ๋งŒ ์ˆœํšŒ
35+
* ๊ณต๊ฐ„ ๋ณต์žก๋„: O(1) - ๋ณ€์ˆ˜ ๋‘ ๊ฐœ๋งŒ ์‚ฌ์šฉ
36+
*/
37+
const maxSubArrayKadane = (nums) => {
38+
let currentMax = nums[0]; // ํ˜„์žฌ ์œ„์น˜๊นŒ์ง€์˜ ์ตœ๋Œ€ ํ•ฉ
39+
let globalMax = nums[0]; // ์ „์ฒด ์ตœ๋Œ€ ํ•ฉ
40+
41+
for (let i = 1; i < nums.length; i++) {
42+
// ํ•ต์‹ฌ: ์ด์ „ ํ•ฉ์— ๋”ํ• ์ง€ vs ์ƒˆ๋กœ ์‹œ์ž‘ํ• ์ง€
43+
currentMax = Math.max(nums[i], currentMax + nums[i]);
44+
globalMax = Math.max(globalMax, currentMax);
45+
}
46+
47+
return globalMax;
48+
};

โ€Žnumber-of-1-bits/smosco.jsโ€Ž

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* @param {number} n
3+
* @return {number}
4+
*/
5+
const hammingWeight = (n) => {
6+
const binaryString = n.toString(2);
7+
let oneCount = 0;
8+
9+
for (const bit of binaryString) {
10+
if (bit === '1') {
11+
oneCount += 1;
12+
}
13+
}
14+
15+
return oneCount;
16+
};
17+
18+
// ๋‹ค๋ฅธ ํ’€์ด
19+
// const hammingWeight = (n) => {
20+
// return n.toString(2).split('1').length - 1;
21+
// };

โ€Žvalid-palindrome/smosco.jsโ€Ž

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* ํ•ต์‹ฌ ์•„์ด๋””์–ด:
3+
* 1. ์ •๊ทœํ‘œํ˜„์‹์œผ๋กœ ์•ŒํŒŒ๋ฒณ๊ณผ ์ˆซ์ž๋งŒ ์ถ”์ถœํ•˜์—ฌ ์†Œ๋ฌธ์ž๋กœ ๋ณ€ํ™˜
4+
* 2. Two Pointer ๋ฐฉ์‹์œผ๋กœ ์–‘ ๋์—์„œ ์ค‘์•™์œผ๋กœ ์ด๋™ํ•˜๋ฉฐ ๋น„๊ต
5+
*
6+
* @param {string} s - ๊ฒ€์‚ฌํ•  ๋ฌธ์ž์—ด
7+
* @return {boolean} - ํŒฐ๋ฆฐ๋“œ๋กฌ ์—ฌ๋ถ€
8+
*
9+
* ์‹œ๊ฐ„ ๋ณต์žก๋„: O(n)
10+
* - replace() ๋ฉ”์„œ๋“œ: O(n) - ๋ฌธ์ž์—ด ์ „์ฒด ์ˆœํšŒ
11+
* - toLowerCase(): O(n) - cleaned ๋ฌธ์ž์—ด ์ˆœํšŒ
12+
* - while ๋ฃจํ”„: O(n/2) โ†’ O(n) - ์ตœ๋Œ€ ๋ฌธ์ž์—ด ๊ธธ์ด์˜ ์ ˆ๋ฐ˜๋งŒํผ ๋ฐ˜๋ณต
13+
* - ์ „์ฒด: O(n) + O(n) + O(n) = O(n)
14+
*
15+
* ๊ณต๊ฐ„ ๋ณต์žก๋„: O(n)
16+
* - cleaned ๋ฌธ์ž์—ด: O(n) - ์ตœ์•…์˜ ๊ฒฝ์šฐ ์ž…๋ ฅ ๋ฌธ์ž์—ด์˜ ๋ชจ๋“  ๋ฌธ์ž๊ฐ€ ์•ŒํŒŒ๋ฒณ/์ˆซ์ž
17+
* - left, right ํฌ์ธํ„ฐ ๋ณ€์ˆ˜: O(1)
18+
* - ์ „์ฒด: O(n)
19+
*/
20+
const isPalindrome = (s) => {
21+
// ์•ŒํŒŒ๋ฒณ๊ณผ ์ˆซ์ž๋งŒ ๋‚จ๊ธฐ๊ณ  ์†Œ๋ฌธ์ž๋กœ ๋ณ€ํ™˜
22+
// \W๋Š” ์•ŒํŒŒ๋ฒณ, ์ˆซ์ž, ์–ธ๋”์Šค์ฝ”์–ด๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ๋ฌธ์ž
23+
// _๋„ ์ œ๊ฑฐํ•ด์•ผ ํ•˜๋ฏ€๋กœ [^a-zA-Z0-9] ์‚ฌ์šฉ
24+
const cleaned = s.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
25+
26+
// Two Pointer ์ ‘๊ทผ๋ฒ•
27+
let left = 0;
28+
let right = cleaned.length - 1;
29+
30+
// ์–‘ ๋์—์„œ ์ค‘์•™์œผ๋กœ ์ด๋™ํ•˜๋ฉฐ ๋น„๊ต
31+
while (left < right) {
32+
if (cleaned[left] !== cleaned[right]) {
33+
return false;
34+
}
35+
left++;
36+
right--;
37+
}
38+
39+
return true;
40+
};

0 commit comments

Comments
ย (0)