Skip to content

[clara-shin] WEEK 03 solutions #1288

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions combination-sum/clara-shin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* 주어진 배열에서 합이 target이 되는 모든 조합 찾기
* 문제 특징: 같은 숫자를 여러 번 사용 가능
*
* 백트래킹 알고리즘: 모든 가능성을 시도해보다가, 해결책이 아닌 경우 이전 단계로 되돌아가 다른 경로를 탐색
* 시간복잡도: O(N^T) (N: candidates 배열의 길이, T: target)
*/

/**
* @param {number[]} candidates
* @param {number} target
* @return {number[][]}
*/
var combinationSum = function (candidates, target) {
const result = [];

/**
* start: 현재 탐색을 시작할 배열의 인덱스
* target: 남은 목표 합계
* currCombination: 현재까지 선택한 숫자들의 배열
*/
const backtrack = (start, target, currCombination) => {
if (target === 0) {
// target을 정확히 맞춘 경우(target이 0인 경우) result에 추가
result.push([...currCombination]);
return;
}
if (target < 0) {
// target이 0보다 작은 경우 빠른 종료
return;
}
for (let i = start; i < candidates.length; i++) {
currCombination.push(candidates[i]); // 현재 숫자 추가
backtrack(i, target - candidates[i], currCombination); // 재귀 호출로 다음단계 진행
currCombination.pop(); // 현재 숫자 제거 (백트래킹) 후 다음 숫자 탐색
}
};
backtrack(0, target, []); // 초기 호출(백트래킹 시작)
return result;
};
35 changes: 35 additions & 0 deletions decode-ways/clara-shin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* 숫자 문자열이 주어졌을 때, 이를 알파벳으로 해독할 수 있는 방법의 수를 구하기
*
* 다이나믹 프로그래밍(DP)
* (1)각 위치에서 시작하여 문자열을 해독하는 방법의 수를 계산
* (2)중복 계산을 피하기 위해 DP를 사용
*/

/**
* @param {string} s
* @return {number}
*/
var numDecodings = function (s) {
if (s.length === 0 || s[0] === '0') return 0;

const dp = new Array(s.length + 1).fill(0);

dp[0] = 1;
dp[1] = s[0] !== '0' ? 1 : 0;
Comment on lines +18 to +19
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dp를 이용해 푸는걸 수식화하는걸 떠올리지 못해서 이부분 저는 제대로 처리못했는데 풀이가 깔끔하네요
제 경우에는 백트래킹으로 풀었는데, 나중에 백트래킹으로 풀어보면 다양한 풀이법으로 접근해보실수 있을거같아 공유드려요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hsskey 공유 감사합니다 ☺️


for (let i = 2; i <= s.length; i++) {
// 한 자리 숫자로 해독하는 경우 (현재 숫자가 1-9)
if (s[i - 1] !== '0') {
dp[i] += dp[i - 1];
}

// 두 자리 숫자로 해독하는 경우 (10-26)
const twoDigit = parseInt(s.substring(i - 2, i));
if (twoDigit >= 10 && twoDigit <= 26) {
dp[i] += dp[i - 2];
}
}

return dp[s.length];
};
24 changes: 24 additions & 0 deletions maximum-subarray/clara-shin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* 최대 부분 배열 합(Maximum Subarray) 또는 카데인 알고리즘(Kadane's Algorithm)
* 정수 배열이 주어졌을 때, 합이 최대가 되는 연속된 부분 배열을 찾아 그 합을 반환하는 문제
*
* DP를 사용하여 현재 위치까지의 부분합을 계산하고, 그 중 최대값을 갱신하는 방식으로 해결
*/

/**
* @param {number[]} nums
* @return {number}
*/
var maxSubArray = function (nums) {
if (nums.length === 0) return 0; // 배열이 비어있으면 0 반환
let maxSum = nums[0]; // 최대 부분합을 저장
let currentSum = nums[0]; // 현재 위치까지의 부분합

for (let i = 1; i < nums.length; i++) {
// 현재 요소를 포함한 부분합과 현재 요소만 선택하는 것 중 큰 값을 선택
currentSum = Math.max(nums[i], currentSum + nums[i]);
maxSum = Math.max(maxSum, currentSum); // 전체 최대 부분합 갱신
}

return maxSum;
};
24 changes: 24 additions & 0 deletions number-of-1-bits/clara-shin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* 숫자를 이진수로 변환하고 1의 개수를 세는 방법
* Follow up: 이 함수가 여러 번 호출된다면?
*
* 단순히 모든 비트를 확인하는 방법: O(log n) 또는 32비트 정수의 경우 O(32)의 시간 복잡도
* ➡️ Brian Kernighan의 알고리즘: O(k)
* 1 비트의 수에 비례하여 실행 시간이 결정
*/

/**
* @param {number} n
* @return {number}
*/
var hammingWeight = function (n) {
let count = 0;

while (n !== 0) {
// n & (n-1)은 n의 마지막 1 비트를 제거
n = n & (n - 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

비트연산을 사용한 풀이는 익숙치않아 생각을 못하고
저는 재귀적으로 풀었는데 이렇게도 풀 수 있네요!

count++;
}

return count;
};
50 changes: 50 additions & 0 deletions valid-palindrome/clara-shin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* 문자열이 팰린드롬인지 확인하는 함수
* 팰린드롬 판단:
* 대문자를 소문자로 변환
* 영숫자(알파벳이랑 숫자)만 남기고 나머지 제거 => 정규식 알면 편함
* 앞에서 읽으나 뒤에서 읽으나 같아야 함
*/

/**정규식 없이 문자열 뒤집는 방법
* @param {string} s
* @return {boolean}
*/
var isPalindrome = function (s) {
s = s.toLowerCase();

let str = ''; // 영숫자만 남길 문자열
for (let i = 0; i < s.length; i++) {
const char = s[i];
// 알파벳이거나 숫자면 str에 추가
if ((char >= 'a' && char <= 'z') || (char >= '0' && char <= '9')) {
str += char;
}
}

// 문자열 뒤집기
let reversedStr = str.split('').reverse().join('');

return str === reversedStr;
};

/**정규식 사용한 투 포인터 방법
* @param {string} s
* @return {boolean}
*/
var isPalindrome2 = function (s) {
const str = s.toLowerCase().replace(/[^a-z0-9]/g, ''); // 영숫자만 남기

// 투 포인터
let left = 0;
let right = str.length - 1;

while (left < right) {
if (str[left] !== str[right]) {
return false;
}
left++;
right--;
}
return true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

투포인터 풀이는 생각못했는데 다양한 풀이법으로
고민하고 풀어보신점이 생각하신점이 좋습니다 👍

};