File tree Expand file tree Collapse file tree 5 files changed +173
-0
lines changed Expand file tree Collapse file tree 5 files changed +173
-0
lines changed Original file line number Diff line number Diff line change
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
+ } ;
Original file line number Diff line number Diff line change
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
+ } ;
Original file line number Diff line number Diff line change
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
+ } ;
Original file line number Diff line number Diff line change
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
+ } ;
Original file line number Diff line number Diff line change
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 - z 0 - 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
+ } ;
You can’t perform that action at this time.
0 commit comments