40. ポートフォリオサムⅡ
候補の配列と目標数値ターゲットを指定して、数値の合計を目標にすることができる候補内のすべての組み合わせを見つけます。
候補内の各番号は、各組み合わせで 1 回のみ使用できます。
説明:
すべての数値 (ターゲット数値を含む) は正の整数です。
ソリューション セットには重複した組み合わせを含めることはできません。
class Solution {
// 执行用时:20 ms, 在所有 Java 提交中击败了9.11%的用户
// 内存消耗:39.9 MB, 在所有 Java 提交中击败了77.52%的用户
//回溯法
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Deque<Integer> dp = new ArrayDeque<>();
int len = candidates.length;
List<List<Integer>> res = new ArrayList<>();
DP(candidates,len , target, dp, res);
List<List<Integer>> listNew=new ArrayList<List<Integer>>();
for (List<Integer> list : res) {
if(!listNew.contains(list)){
listNew.add(list);
}
}
return listNew;
}
public void DP(int[] candidates,int n, int target, Deque<Integer> dp,List<List<Integer>> res) {
// //dp[n,k],当n=0时,返回当前数组中的数
if(target == 0){
List list = new ArrayList<>(dp);
Collections.sort(list);
res.add(list);
return;
}
if(n == 0){
return;
}
int times = target / candidates[n - 1];
times = Math.min(1,times);
for(int i = 0;i <= times;++i){
for(int j = 0; j < i; ++j){
dp.addLast(candidates[n - 1]);
}
DP(candidates, n - 1,target - candidates[n - 1] * i, dp, res);
for(int j = 0; j < i; ++j){
dp.removeLast();
}
}
return;
}
}