Skip to content

Commit 3289b62

Browse files
authored
Merge pull request #2095 from rivkode/main
[rivkode] WEEK 03 solutions
2 parents 63c0871 + df55f63 commit 3289b62

File tree

4 files changed

+244
-0
lines changed

4 files changed

+244
-0
lines changed

combination-sum/rivkode.java

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
3+
1. 문제 이해
4+
5+
모든 조합 (중복 허용) 을 통해 target 숫자를 찾는다.
6+
7+
2
8+
2, 2
9+
2, 2, 2
10+
2, 2, 2, 2 - 초과
11+
2, 2, 3 - 타겟
12+
2, 2, 6 - 초과
13+
2, 3
14+
2, 3, 3
15+
...
16+
6,
17+
6, 6
18+
19+
20+
21+
2. 알고리즘
22+
23+
dfs ?
24+
25+
3. 예외 케이스
26+
일치 케이스 없는 경우 ?
27+
다 돌면 예외가 있을까 ?
28+
29+
4. 구현
30+
31+
종료 트리거는 일치할 경우
32+
target 숫자보다 높은 경우는 뒤로 감
33+
뒤로 가서 다음 숫자를 넣어 보자
34+
35+
candidates 정렬
36+
dfs 로 진행, 입력 파라미터는 더할 숫자 ?
37+
대소 비교해서 만약 더 작으면 같은 숫자 넣고 더 크면 뒤로 이동
38+
39+
dfs 함수
40+
41+
새로운 Num 입력받음
42+
입력받은 숫자를 tmp 리스트에 더하고
43+
전체 합이 target 에 대해 대소 관계 비교
44+
45+
1. 크다면 뒤로 이동하고 다음 숫자 입력
46+
2. 같다면 result에 넣고 뒤로 이동
47+
3. 작다면 동일한 숫자 넣기
48+
49+
이상하게 dfs 를 구현했다. 순서도 맞지 않고
50+
for문 구현, 인자, 접근 방법 모두 틀렸다.
51+
기억하자
52+
1. 호출은 main 에서 dfs() 한다
53+
2. 백트래킹 for 문은 dfs() 내에서 구현한다.
54+
55+
답변을 보고 오니 백트래킹을 어떻게 해야겠다는 감이 왔다.
56+
57+
뒤로 가는걸 어떻게 구현할까 생각했는데 For 문에서 tmp에 새로운 숫자를 넣고 제거하면서 그 사이에 dfs 를 넣으면 되는거였다.
58+
59+
60+
for loop
61+
tmp.add num
62+
dfs()
63+
tmp.remove num
64+
65+
식으로 말이다.
66+
67+
*/
68+
69+
import java.util.*;
70+
71+
class Solution {
72+
private int t;
73+
private List<List<Integer>> result;
74+
75+
public List<List<Integer>> combinationSum(int[] candidates, int target) {
76+
t = target;
77+
result = new ArrayList<>();
78+
Arrays.sort(candidates);
79+
List<Integer> nums = new ArrayList<>();
80+
81+
dfs(candidates, 0, nums, 0);
82+
83+
return result;
84+
}
85+
86+
public void dfs(int[] candidates, int total, List<Integer> nums, int start) {
87+
if (total > t) return; // total이 target 보다 크다면 이전으로 돌아가기 위해 return
88+
if (total == t) { // 정답일 경우 해당 값 추가 및 return
89+
result.add(new ArrayList<>(nums)); // nums 와 new ArrayList<>(nums) 차이 이해하기
90+
// 빈 배열로 저장되길래 왜 저때의 값이 저장안되지 ? 라고 생각했지만
91+
// 당연히 안됨. ref 주소값을 저장했으므로 나중에는 이 Nums가 모두 빈배열이 되므로
92+
return;
93+
}
94+
95+
for (int i=start; i < candidates.length; i++) { // start 부터 시작하는것 포인트!
96+
int num = candidates[i];
97+
nums.add(num);
98+
dfs(candidates, total + num, nums, i);
99+
nums.remove(nums.size() - 1); // 다음에는 stack 사용하자
100+
}
101+
}
102+
}

maximum-subarray/rivkode.java

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
1. 문제 이해
3+
4+
[-2,1,-3,4,-1,2,1,-5,4]
5+
* 정답부분 참고
6+
각 인덱스를 시작점으로 잡고 모든 부분에 대한 부분 배열의 합을 구한다
7+
이전에 계산했던 내용을 저장해서 사용한다
8+
-> 이렇게 계산해도 Time Limit Exceeded 발생하네 ..
9+
10+
결국엔 이렇게 해도 n^2 시간이 발생하므로 시간초과
11+
포인트는 n^2 가 걸리는 시간을 어떻게 nlogn이나 n으로 줄일 수 있는지임
12+
13+
* 정답 부분 참고
14+
누적합이 음수라면 시작 인덱스를 다음으로 과감하게 옮긴다
15+
16+
17+
이 문제는 직관적으로 문제를 바라보는것이 중요했다.
18+
아마도 이렇게 접근하는건 어떨까 ?
19+
나는 최대합을 구하고싶었다. 부분 배열로!
20+
부분배열이라는 것은 연속된다는 것이 특징이다.
21+
22+
즉, 연속되어야 하므로 이전의 합들이 만약 음수라면 ? 이 부분들은 필요가 없어지므로 과감히 버릴 수 있다는 것을 아는 것이 포인트였다.
23+
24+
버린다는 것의 의미는 ? -> 현재 인덱스의 값과 이전 전체의 값들의 합을 비교해서 현재 인덱스부터 다시 출발한다는 것이다. 그러므로 비교해서 더 큰값을 total로 가져가는 것이다.
25+
26+
만약 이걸 처음부터 알았다면 그리고 기존에 작성한 n^2 를 소요하면서 모든 합을 구하려 했을때 비효율적인것을 직감했다면 다른 방법으로 접근할 수 있었어야 했다.
27+
28+
그리고 처음 total, maxTotal을 첫번째 인덱스로 지정해줬기 때문에 i 인덱스는 1부터 시작해야한다
29+
30+
31+
*/
32+
33+
import java.util.*;
34+
35+
class Solution {
36+
public int maxSubArray(int[] nums) {
37+
int total = nums[0];
38+
int maxTotal = nums[0];
39+
40+
41+
for (int i=1; i<nums.length; i++) {
42+
total = Math.max(nums[i], total + nums[i]);
43+
maxTotal = Math.max(total, maxTotal);
44+
}
45+
46+
return maxTotal;
47+
48+
// for (int i=0; i<nums.length; i++) {
49+
// int total = 0;
50+
// for (int j=i; j<nums.length; j++) {
51+
// total += nums[j];
52+
// max = Math.max(total, max);
53+
// if (total < 0) {
54+
// break;
55+
// }
56+
// }
57+
// }
58+
59+
// return max;
60+
}
61+
62+
private int sum(int[] arr, int start, int end) {
63+
int cnt = 0;
64+
for (int i=start; i<end + 1; i++) {
65+
cnt += arr[i];
66+
}
67+
return cnt;
68+
}
69+
}

number-of-1-bits/rivkode.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
Integer.toBinaryString() 메서드 기억하기
3+
*/
4+
5+
6+
import java.util.*;
7+
8+
class Solution {
9+
public int hammingWeight(int n) {
10+
String s = Integer.toBinaryString(n);
11+
int count = 0;
12+
13+
for (int i=0; i<s.length(); i++) {
14+
char c = s.charAt(i);
15+
if (c == 49) {
16+
count += 1;
17+
}
18+
}
19+
20+
return count;
21+
}
22+
}
23+

valid-palindrome/rivkode.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
1. 문제 이해
3+
입력받은 글자에 대해 뒤집어도 동일한 글자인지 아닌지를 판단
4+
5+
2. 예외 케이스
6+
빈 문자열, 글자가 아닌 다른 내용일 경우 제거
7+
8+
3. 알고리즘
9+
단순 루프
10+
11+
4. 구현
12+
13+
글자를 입력받고 글자가 아닌 내용에 대해서는 필터링한다
14+
전체 길이를 구하고 2포인터로 왼쪽, 오른쪽을 서로 줄여가면서
15+
같거나 교차할때 종료
16+
17+
다른 부분이 있으면 false 반환, 모두 통과하면 true 반환
18+
19+
빈 값일경우 바로 true
20+
21+
22+
*/
23+
24+
import java.util.*;
25+
26+
class Solution {
27+
public boolean isPalindrome(String s) {
28+
String result = s.replaceAll("[^a-zA-Z0-9]", "");
29+
result = result.toLowerCase();
30+
31+
int len = result.length();
32+
int left = 0;
33+
int right = len - 1;
34+
35+
while (left < right) {
36+
char leftS = result.charAt(left);
37+
char rightS = result.charAt(right);
38+
39+
if (leftS != rightS) {
40+
return false;
41+
}
42+
43+
left += 1;
44+
right -= 1;
45+
}
46+
47+
return true;
48+
}
49+
}
50+

0 commit comments

Comments
 (0)