1 解題思想
原題是說給定一些數字和一個目標值,從這些數字中挑選幾個加起來,加起來後他的和正好等於目標值,其中一個數字可以選擇多次。要求輸出的不能有重複,並且組內的順序是不能降序的。
這道題首先必須要想到的就是排序了,排序是非常基本,又非常常用的一種操作。
然後我們需要排除重複的(注意可以重複選擇一個數,所以重複的最好先去掉,因為我們需要進行遞迴回溯,這樣做可以降低無謂的開銷)
隨後我們就開始求解,求解的做法是採用遞迴的回溯,每一次遞迴傳遞還需要的數值reserve,同時記錄已經選擇的數字,原則上當前選擇的數字需要大於等於上一個,所以再加上一個index表示可以從哪個索引開始選擇。
然後遇到reserve為0就加入最終結果,遇不到就不加咯~~~ 2 原題
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
•All numbers (including target) will be positive integers.
•Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
•The solution set must not contain duplicate combinations.
For example, given candidate set 2,3,6,7 and target 7,
A solution set is:
[7]
[2, 2, 3] 3 AC解
public class Solution { /** * 可以用一個計數的數組來降低開銷,遞迴的時候只改變數組裡選擇的值,最後reserve=0再產生list * **/ int n; int nums[]; List<List<Integer>> result; //當前集合,當前使用的數字位置,當前還剩多少 public void find(List<Integer> values,int index,int reserve){ if(reserve==0){ ArrayList<Integer> item=new ArrayList<Integer>(); item.addAll(values); result.add(item); } for(int i=index;i<n;i++){ if(nums[i]<=reserve){ values.add(nums[i]); find(values,i,reserve-nums[i]); values.remove(values.size()-1); } } } public List<List<Integer>> combinationSum(int[] candidates, int target) { //排序然後去除重複的 Arrays.sort(candidates); //去除重複,這樣省心 int i,j,k,n; n=1; for(i=1;i<candidates.length;i++){ if(candidates[i]!=candidates[i-1]){ candidates[n++]=candidates[i]; } } this.nums=candidates; this.n=n; this.result=new ArrayList<List<Integer>>(); find(new ArrayList<Integer>(),0,target); return this.result; }}