Skip to content

Commit 84a19e1

Browse files
committed
feat: comvination-sum solve 더 개선된 로직 필요
1 parent 8c2836e commit 84a19e1

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

combination-sum/haxr369.java

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import java.util.ArrayList;
2+
import java.util.HashSet;
3+
import java.util.List;
4+
import java.util.Set;
5+
6+
/**
7+
* 1번째 풀이는 2번째 풀이를 개선한 것.
8+
* 2번째 풀이는 dfs를 이욯해서 중복순열의 경우의 수를 찾기 때문에 시간복잡도가 매우 높다.
9+
* 또한 중복순열에서 중복을 제거하면서도 낭비되는 연산이 매우 많다.
10+
*
11+
*/
12+
class Solution {
13+
14+
/**
15+
* candidates의 후보들은 중복 사용이 가능하다.
16+
* 모든 후보는 구별된다.=> 중복이 없다.
17+
*
18+
* Runtime: 48 ms (Beats 5.56%)
19+
* Memory: 46.96 MB (Beats 6.1%)
20+
* Space Complexity: O(N) + O(K)
21+
* - 사용되는 후보를 Set으로 관리하기 => O(N)
22+
* - 후보가 사용된 횟수를 관리하기 => O(K)
23+
* > O(N) + O(K)
24+
* Time Complexity: O(N)
25+
* - 후보 하나를 선택해서 target과 비교 => O(N^M)
26+
* - target이 0이 되거나 누적 값이 더 커질 때까지 스택을 쌓기
27+
* - 최대 누적할 수 있는 횟수는 40 / 2 = 20회 => O(20) = O(M)
28+
* > O(N)*O(M)
29+
*/
30+
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
31+
Set<List<Integer>> set = new HashSet<>();
32+
Set<Integer> acc = new HashSet<>();
33+
int[] usedCount = new int[44];
34+
dfs(set, acc, usedCount, target, candidates);
35+
36+
List<List<Integer>> ans = new ArrayList<>(set);
37+
return ans;
38+
}
39+
40+
/**
41+
* set: return용 조합 저장
42+
* acc: 사용 후보 누적
43+
* usedCount: 후보별 사용된 횟수 저장
44+
* target: 만들 수
45+
*/
46+
private void dfs(Set<List<Integer>> set, Set<Integer> acc, int[] usedCount, int target, int[] candidates) {
47+
// 완성된 경우 리턴하기
48+
if (target == 0) {
49+
// System.out.println("==========완성!! -> "+acc);
50+
List<Integer> tmp = new ArrayList<>();
51+
for (int n : candidates) {
52+
if (acc.contains(n)) {
53+
for (int i = 0; i < usedCount[n]; i++) {
54+
tmp.add(n);
55+
}
56+
}
57+
}
58+
set.add(tmp);
59+
return;
60+
}
61+
62+
for (int n : candidates) {
63+
// target 보다 작은 후보 사용하기
64+
65+
if (target >= n) {
66+
// System.out.println("candi->"+n);
67+
usedCount[n]++;
68+
acc.add(n);
69+
// System.out.println(". next target->"+(target-n));
70+
dfs(set, acc, usedCount, target - n, candidates);
71+
// 원복하기
72+
usedCount[n]--;
73+
if (usedCount[n] == 0) {
74+
acc.remove(n);
75+
}
76+
}
77+
}
78+
}
79+
}

0 commit comments

Comments
 (0)