Skip to content

Commit a204356

Browse files
authored
Merge pull request #1288 from clara-shin/main
[clara-shin] WEEK 03 solutions
2 parents 11b33a3 + 0fc3c26 commit a204356

File tree

5 files changed

+173
-0
lines changed

5 files changed

+173
-0
lines changed

combination-sum/clara-shin.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* 주어진 배열에서 합이 target이 되는 모든 조합 찾기
3+
* 문제 특징: 같은 숫자를 여러 번 사용 가능
4+
*
5+
* 백트래킹 알고리즘: 모든 가능성을 시도해보다가, 해결책이 아닌 경우 이전 단계로 되돌아가 다른 경로를 탐색
6+
* 시간복잡도: O(N^T) (N: candidates 배열의 길이, T: target)
7+
*/
8+
9+
/**
10+
* @param {number[]} candidates
11+
* @param {number} target
12+
* @return {number[][]}
13+
*/
14+
var combinationSum = function (candidates, target) {
15+
const result = [];
16+
17+
/**
18+
* start: 현재 탐색을 시작할 배열의 인덱스
19+
* target: 남은 목표 합계
20+
* currCombination: 현재까지 선택한 숫자들의 배열
21+
*/
22+
const backtrack = (start, target, currCombination) => {
23+
if (target === 0) {
24+
// target을 정확히 맞춘 경우(target이 0인 경우) result에 추가
25+
result.push([...currCombination]);
26+
return;
27+
}
28+
if (target < 0) {
29+
// target이 0보다 작은 경우 빠른 종료
30+
return;
31+
}
32+
for (let i = start; i < candidates.length; i++) {
33+
currCombination.push(candidates[i]); // 현재 숫자 추가
34+
backtrack(i, target - candidates[i], currCombination); // 재귀 호출로 다음단계 진행
35+
currCombination.pop(); // 현재 숫자 제거 (백트래킹) 후 다음 숫자 탐색
36+
}
37+
};
38+
backtrack(0, target, []); // 초기 호출(백트래킹 시작)
39+
return result;
40+
};

decode-ways/clara-shin.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* 숫자 문자열이 주어졌을 때, 이를 알파벳으로 해독할 수 있는 방법의 수를 구하기
3+
*
4+
* 다이나믹 프로그래밍(DP)
5+
* (1)각 위치에서 시작하여 문자열을 해독하는 방법의 수를 계산
6+
* (2)중복 계산을 피하기 위해 DP를 사용
7+
*/
8+
9+
/**
10+
* @param {string} s
11+
* @return {number}
12+
*/
13+
var numDecodings = function (s) {
14+
if (s.length === 0 || s[0] === '0') return 0;
15+
16+
const dp = new Array(s.length + 1).fill(0);
17+
18+
dp[0] = 1;
19+
dp[1] = s[0] !== '0' ? 1 : 0;
20+
21+
for (let i = 2; i <= s.length; i++) {
22+
// 한 자리 숫자로 해독하는 경우 (현재 숫자가 1-9)
23+
if (s[i - 1] !== '0') {
24+
dp[i] += dp[i - 1];
25+
}
26+
27+
// 두 자리 숫자로 해독하는 경우 (10-26)
28+
const twoDigit = parseInt(s.substring(i - 2, i));
29+
if (twoDigit >= 10 && twoDigit <= 26) {
30+
dp[i] += dp[i - 2];
31+
}
32+
}
33+
34+
return dp[s.length];
35+
};

maximum-subarray/clara-shin.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* 최대 부분 배열 합(Maximum Subarray) 또는 카데인 알고리즘(Kadane's Algorithm)
3+
* 정수 배열이 주어졌을 때, 합이 최대가 되는 연속된 부분 배열을 찾아 그 합을 반환하는 문제
4+
*
5+
* DP를 사용하여 현재 위치까지의 부분합을 계산하고, 그 중 최대값을 갱신하는 방식으로 해결
6+
*/
7+
8+
/**
9+
* @param {number[]} nums
10+
* @return {number}
11+
*/
12+
var maxSubArray = function (nums) {
13+
if (nums.length === 0) return 0; // 배열이 비어있으면 0 반환
14+
let maxSum = nums[0]; // 최대 부분합을 저장
15+
let currentSum = nums[0]; // 현재 위치까지의 부분합
16+
17+
for (let i = 1; i < nums.length; i++) {
18+
// 현재 요소를 포함한 부분합과 현재 요소만 선택하는 것 중 큰 값을 선택
19+
currentSum = Math.max(nums[i], currentSum + nums[i]);
20+
maxSum = Math.max(maxSum, currentSum); // 전체 최대 부분합 갱신
21+
}
22+
23+
return maxSum;
24+
};

number-of-1-bits/clara-shin.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* 숫자를 이진수로 변환하고 1의 개수를 세는 방법
3+
* Follow up: 이 함수가 여러 번 호출된다면?
4+
*
5+
* 단순히 모든 비트를 확인하는 방법: O(log n) 또는 32비트 정수의 경우 O(32)의 시간 복잡도
6+
* ➡️ Brian Kernighan의 알고리즘: O(k)
7+
* 1 비트의 수에 비례하여 실행 시간이 결정
8+
*/
9+
10+
/**
11+
* @param {number} n
12+
* @return {number}
13+
*/
14+
var hammingWeight = function (n) {
15+
let count = 0;
16+
17+
while (n !== 0) {
18+
// n & (n-1)은 n의 마지막 1 비트를 제거
19+
n = n & (n - 1);
20+
count++;
21+
}
22+
23+
return count;
24+
};

valid-palindrome/clara-shin.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* 문자열이 팰린드롬인지 확인하는 함수
3+
* 팰린드롬 판단:
4+
* 대문자를 소문자로 변환
5+
* 영숫자(알파벳이랑 숫자)만 남기고 나머지 제거 => 정규식 알면 편함
6+
* 앞에서 읽으나 뒤에서 읽으나 같아야 함
7+
*/
8+
9+
/**정규식 없이 문자열 뒤집는 방법
10+
* @param {string} s
11+
* @return {boolean}
12+
*/
13+
var isPalindrome = function (s) {
14+
s = s.toLowerCase();
15+
16+
let str = ''; // 영숫자만 남길 문자열
17+
for (let i = 0; i < s.length; i++) {
18+
const char = s[i];
19+
// 알파벳이거나 숫자면 str에 추가
20+
if ((char >= 'a' && char <= 'z') || (char >= '0' && char <= '9')) {
21+
str += char;
22+
}
23+
}
24+
25+
// 문자열 뒤집기
26+
let reversedStr = str.split('').reverse().join('');
27+
28+
return str === reversedStr;
29+
};
30+
31+
/**정규식 사용한 투 포인터 방법
32+
* @param {string} s
33+
* @return {boolean}
34+
*/
35+
var isPalindrome2 = function (s) {
36+
const str = s.toLowerCase().replace(/[^a-z0-9]/g, ''); // 영숫자만 남기
37+
38+
// 투 포인터
39+
let left = 0;
40+
let right = str.length - 1;
41+
42+
while (left < right) {
43+
if (str[left] !== str[right]) {
44+
return false;
45+
}
46+
left++;
47+
right--;
48+
}
49+
return true;
50+
};

0 commit comments

Comments
 (0)