候補の配列とターゲット数のターゲットが与えられた場合、数の合計をターゲットにすることができる候補のすべての組み合わせを見つけます。
候補の各番号は、各組み合わせで1回のみ使用できます。
入力:候補= [10,1,2,7,6,1,5]、目標= 8、
ソリューションセットである:
[
[1,7]、
[1、2、5]、
[2]、[6]、
[1、1、6]
]
問題の解決策:この問題の解決策は基本的にLeetcode39(結合合計)と同じですが、重複排除ステップがもう1つあります。たとえば、配列[2,2,3]とtarget:5の場合、通常のバックトラッキング方法に従うと、 Leetcode39(結合合計)と同じソリューションを使用すると、2つの重複した回答[2,3]と[2,3]が返されます。バックトラッキングプロセスで重複を排除する必要があります。重複を排除する最も効果的な方法は、リストを作成することですコンテナには、配列に出現する要素と要素が出現する回数が格納されます。再帰すると、元の配列を再帰するのではなく、構築されたリストコンテナが出現します。要素はn回出現し、要素を0〜n回再帰できることを示しています。つまり、ソリューションセットの配列には0〜n回存在する可能性があります。バックトラッキングを使用してこれらの0〜n回を列挙するだけで、すべての結果を取得し、重複排除の目的を達成できます。
class Solution {
private final Stack<Integer>stack=new Stack<>();
private final List<List<Integer>>res=new ArrayList<>();
private final List<int[]>arrayElements=new LinkedList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Solution.sort(candidates);
int repeat=1;
//构造List容器,存储数组中的元素及其出现次数
for(int i=0;i< candidates.length-1;i++){
if(candidates[i]==candidates[i+1])
repeat++;
else{
arrayElements.add(new int[]{
candidates[i],repeat});
repeat=1;
}
}
arrayElements.add(new int[]{
candidates[candidates.length-1],repeat});
backTrace(candidates,0,0,target);
return res;
}
private void backTrace(int[]candidates,int pos,int sum,int target){
if(sum==target)
res.add(new ArrayList<>(stack));
if(pos>=arrayElements.size())
return;
int element=arrayElements.get(pos)[0];
int repeat=arrayElements.get(pos)[1];
if(target-sum<element)
return;
//执行一次循环,则解集数组中出现一次该元素
for(int i=0;i<repeat;i++){
stack.push(element);
backTrace(candidates,pos+1,sum+element*(i+1),target);
}
for(int i=0;i<repeat;i++){
stack.pop();
}
//结果数组中没有该元素
backTrace(candidates,pos+1,sum,target);
}
//快排算法
public static void sort(int[]args){
quickSort(args,0,args.length-1);
}
private static void quickSort(int[]args,int start,int end){
if(start>=end)
return;
int pivot=args[start];
int left=start;
int right=end;
while(left<right){
while(args[right]>pivot&&left<right)
right--;
while(args[left]<=pivot&&left<right)
left++;
change(args,right,left);
}
change(args,start,left);
quickSort(args,start,left-1);
quickSort(args,left+1,end);
}
private static void change(int[]args,int x,int y){
int temp=args[x];
args[x]=args[y];
args[y]=temp;
}
}