Skip to content

Commit 6edaca7

Browse files
authored
[namuuCY] WEEK 03 Solutions (#2709)
1 parent 9fdae26 commit 6edaca7

5 files changed

Lines changed: 202 additions & 0 deletions

File tree

combination-sum/namuuCY.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// 문제풀이 흐름
2+
// 하나를 집어넣고, 모자라면 이전과 동일한걸 집어넣거나 더 큰걸 집어넣는 방식으로 계속 확인
3+
// -> 백트래킹 방식
4+
5+
// n = candidates.length / m = candidates[0] 라 할때,
6+
// 시간복잡도 :
7+
// 이론상 O(n ^ (target / m))
8+
// 150 조합 이내로 뽑히게끔 만들어뒀으므로 알아서 잘되지 않았을까...
9+
// 공간복잡도 :
10+
// O(target / m) - 재귀 깊이만큼
11+
12+
13+
class Solution {
14+
15+
List<List<Integer>> answer = new ArrayList<>();
16+
int[] candidates;
17+
int target;
18+
19+
public List<List<Integer>> combinationSum(int[] candidates, int target) {
20+
this.candidates = candidates;
21+
this.target = target;
22+
23+
backtracking(new ArrayList<>(), 0, target);
24+
return answer;
25+
}
26+
27+
public void backtracking(List<Integer> combination, int currentIdx, int remainder) {
28+
if (remainder == 0) {
29+
answer.add(new ArrayList<>(combination));
30+
return;
31+
} else if (remainder < 0) {
32+
return;
33+
}
34+
35+
for (int i = currentIdx ; i < candidates.length ; i++) {
36+
combination.add(candidates[i]);
37+
backtracking(combination, i, remainder - candidates[i]);
38+
combination.remove(combination.size() - 1);
39+
}
40+
}
41+
}

decode-ways/namuuCY.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// 문제 풀이 흐름
2+
// DP[i] = i - 1 번째 인덱스 char를 끝으로 하는 조합
3+
// 문제는 case를 다 분리할 수 밖에 없는건가?
4+
// 7~9 이면 앞자리가 1인지 확인 -> 있으면 두가지 합해야함 / 아니면 한가지만
5+
// 0이면 앞자리가 반드시 1,2 이어야함 -> 무조건 한가지
6+
// 1~6이면 앞자리가 1,2인지 확인 -> 있으면 두가지 합해야함 / 아니면 한가지만
7+
// 이러면 너무 더러운 느낌?
8+
// if () {
9+
// if ()
10+
// } else if () {
11+
// if ()
12+
// } else {
13+
// }
14+
15+
// 추가적으로 고려하지 못한 사항 : 01, 001 과 같은 경우
16+
17+
// n = s의 길이
18+
// 시간복잡도 : O(n)
19+
// 공간복잡도 : O(n)
20+
21+
22+
class Solution {
23+
24+
String s;
25+
int length;
26+
int[] DP;
27+
28+
public int numDecodings(String s) {
29+
30+
this.s = s;
31+
this.length = s.length();
32+
this.DP = new int[this.length + 1];
33+
34+
DP[0] = 1;
35+
36+
for (int i = 1 ; i < this.length + 1; i ++) {
37+
38+
if (canDecodeSingle(i)) {
39+
DP[i] += DP[i - 1];
40+
}
41+
42+
if (i >= 2 && canDecodePair(i)) {
43+
DP[i] += DP[i - 2];
44+
}
45+
}
46+
47+
return DP[this.length];
48+
}
49+
50+
private boolean canDecodeSingle(int currentIdx) {
51+
return s.charAt(currentIdx - 1) != '0';
52+
}
53+
54+
private boolean canDecodePair(int currentIdx) {
55+
char currentChar = s.charAt(currentIdx - 1);
56+
char prevChar = s.charAt(currentIdx - 2);
57+
return prevChar == '1'
58+
|| (prevChar == '2' && currentChar <= '6');
59+
}
60+
}

maximum-subarray/namuuCY.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// 문제 풀이 흐름
2+
// 맨처음에 생각한 풀이는
3+
// 누적합을 기준으로,
4+
// 누적합의 오른쪽 최대 - 왼쪽 최소 의 값이 제일 큰걸 구하면 된다고 생각했음.
5+
// 예를 들어서 nums = [-2,1,-3,4,-1,2,1,-5,4] 라면
6+
// 누적합은 [-2 -1 -4 0 -1 1 2 -3] 이 되는데, 값의 최대는 2에서 -4를 뺸 6이 최대라고 생각했음.
7+
// 그래서 어느 한 좌표(왼쪽)를 순회하면서
8+
// 이 인덱스의 오른쪽(왼쪽 인덱스 +1 부터 끝까지)의 누적합의 최소를 구하면 된다고 생각했음.
9+
// 이 위를 구하기 위해서 누적합에 대해 세그먼트 트리를 구축해두려고 했음.
10+
// 그러면 세그먼트 트리 만드는데 nlogn + 1중 for 문 * log n 조회니까 최대 nlogn의 시간복잡도로 문제를 풀수있음 / 공간복잡도는 O(n log n)이 될것.
11+
12+
// 근데 제시된 풀이를 보니까 1차원 DP로 푸는것을 봤음.
13+
// DP[i] = Math.max(nums[i], DP[i - 1] + nums[i]);
14+
// 혹은 = nums[i] + (DP[i - 1] > 0) ? DP[i - 1] : 0; 이 되겠지.
15+
// 이렇게 하면 시간복잡도 O(n) 공간복잡도 O(n)이라 내 풀이보다 훨씬좋다
16+
17+
class Solution {
18+
19+
public int maxSubArray(int[] nums) {
20+
int[] DP = new int[nums.length + 1];
21+
int maxSum = - 200000;
22+
23+
for (int i = 0 ; i < nums.length; i ++) {
24+
DP[i + 1] = nums[i] + (DP[i] > 0 ? DP[i] : 0);
25+
maxSum = Math.max(maxSum, DP[i + 1]);
26+
}
27+
28+
return maxSum;
29+
}
30+
}

number-of-1-bits/namuuCY.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// 문제풀이 흐름
2+
// 어떤 숫자를 2진수로 나타냈을때, 1의 개수를 구하는 것이므로
3+
// 2진수 변환과정에서 나오는 모든 1의 갯수만 세면 된다.
4+
5+
// 숫자 n에 대하여
6+
// 시간복잡도 : O(logn)
7+
// 공간복잡도 : O(1)
8+
9+
class Solution {
10+
public int hammingWeight(int n) {
11+
int answer = 0;
12+
13+
while (n > 0) {
14+
if (n % 2 == 1) answer ++;
15+
n /= 2;
16+
}
17+
18+
return answer;
19+
}
20+
}

valid-palindrome/namuuCY.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// 문제 풀이 흐름 1
2+
// 먼저, 알파벳이 아닌 글자는 다 쳐내는 작업이 필요
3+
// 그 다음 알파벳으로만 만들어진 문자열에 대해 팰린드롬 확인
4+
// 길이 확인 후
5+
// 맨처음에서부터 중간까지, 대칭 값이 맞는지 확인
6+
7+
// n = s의 길이라 할때
8+
// 시간복잡도 : O(n)
9+
// 공간복잡도 : O(n) - 어쩔수없이 trimming한 문자열은 저장해야하므로
10+
11+
// 문제 풀이 흐름 2
12+
13+
// 문자열 그대로 팰린드롬 확인 스타트
14+
// 맨 앞과 뒤의 인덱스에서 시작해서
15+
// 알파벳이 아닌 다른 문자라면 skip
16+
// 알파벳이라면 비교
17+
18+
// n = s의 길이라 할때
19+
// 시간복잡도 : O(n)
20+
// 공간복잡도 : O(1)
21+
22+
23+
class Solution {
24+
public boolean isPalindrome(String s) {
25+
int rightIdx = s.length() - 1;
26+
27+
for (int leftIdx = 0 ; leftIdx <= rightIdx ; leftIdx ++) {
28+
if (!isValid(s.charAt(leftIdx))) continue;
29+
30+
// rightIdx 조절
31+
while (leftIdx <= rightIdx && !isValid(s.charAt(rightIdx))) {
32+
rightIdx--;
33+
}
34+
35+
if (!isSameChar(s.charAt(leftIdx), s.charAt(rightIdx))) {
36+
return false;
37+
}
38+
rightIdx-- ;
39+
}
40+
41+
return true;
42+
}
43+
44+
private boolean isValid(char c) {
45+
return 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9';
46+
}
47+
48+
private boolean isSameChar(char a, char b) {
49+
return Character.toLowerCase(a) == Character.toLowerCase(b);
50+
}
51+
}

0 commit comments

Comments
 (0)