1. 程式人生 > >LeetCode筆記——39組合總和

LeetCode筆記——39組合總和

題目:

給定一個無重複元素的陣列 candidates 和一個目標數 target ,找出 candidates 中所有可以使數字和為 target 的組合。

candidates 中的數字可以無限制重複被選取。

說明:

  • 所有數字(包括 target)都是正整數。
  • 解集不能包含重複的組合。 

示例 1:

輸入: candidates = [2,3,6,7], target = 7,
所求解集為:
[
  [7],
  [2,2,3]
]

示例 2:

輸入: candidates = [2,3,5], target = 8,
所求解集為:
[
  [2,2,2,2],
  [2,3,3],
  [3,5]
]

思路:總的是使用遞歸回溯的思想,具體參考了網上大神的程式碼以及leetcode中執行最快的程式碼。以下對這兩種程式碼進行分析。

程式碼:

class Solution {            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) {               //利用sort進行排序         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;     } }

執行最快的程式碼:

基本上也是使用遞迴的思想。使用相加的思想。

class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> res=new ArrayList<List<Integer>>();
        ArrayList<Integer> cur=new ArrayList<>();
        int sum=0;
        //校驗
        if(candidates==null || candidates.length==0) {
            return res;
        }
        dfs(res,candidates,sum,cur,target,0);
        return res;


    }
    public void dfs(List<List<Integer>>res,int[] candidates,int sum,ArrayList<Integer>cur,int target,int start){
        if(sum==target){
            res.add(new ArrayList<>(cur));
            return ;
        }
        for(int i=start;i<candidates.length;i++){
            if(sum+candidates[i]<=target){
                sum+=candidates[i];
                cur.add(candidates[i]);
                dfs(res,candidates,sum,cur,target,i);
                sum-=candidates[i];
                cur.remove(cur.size()-1);
            }
        }
    }