1. 程式人生 > >LeetCode:39 combination sum ;

LeetCode:39 combination sum ;

一、

首先這個題和上一篇文章的遞歸回溯很像

求子集(上一篇文章的連結)

但是上一篇文章是求子集,但是還是不同的,舉一個例子

比如candidates=[2,3,6,7] target=7

上一篇求子集結果是什麼呢,結果中只有[7]是符合target的,但是我們這個題的結果是[7],[2,2,3]

因為求子集啊,子集裡面不包含同一個位置的相同元素(也就是不會出現[2,2],[2,2,2];但是如果集合是[2,2,6,7],子集會出現[2],[2][2,2],[2,6][2,6])

而我們這個題呢,求的是組合和,而且看例子,是可以有同一個位置的相同元素的組合的

那麼就可以這麼想,原先我們遞迴始終是從當前位置i的下一個位置i+1遞迴,那麼我們現在第一次遞迴可以從當前位置i繼續遞迴(也就是可以考慮當前元素);然後問題來了,第二次遞迴,也就是一直到第一次的遞迴方式走到頭了,執行i+1的第二個遞迴

下面這個圖是別人部落格裡[2,3,5]的例子,可以參考看一下

(1)我的java程式碼(可以說,我沒有見過網上有我這種使用兩個遞迴的方法,我猜。我挺喜歡左程雲老師的程式碼風格的,遞迴題就全部用遞迴,不巢狀迴圈)

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List <Integer> result=new ArrayList<Integer>();
        List<List<Integer>> results =new ArrayList<List<Integer>>();
        if(candidates==null||candidates.length==0)
            return results;
        //傳入的引數,陣列,二維list,每一行的List,sum和,目標和target
        Arrays.sort(candidates);
        process(candidates,0,results,result,0,target);
        return results;
    }
    public static void process
    (int[]candidates,int i,List<List<Integer>>results,List<Integer>result,int sum,int target){
        if(i>candidates.length-1||sum>target)
            return;
        if(target==sum){
            results.add(new ArrayList<Integer>(result));
            return;
        }
        sum+=candidates[i];
        result.add(candidates[i]);
        process(candidates,i,results,result,sum,target);
        result.remove(result.size()-1);
        sum-=candidates[i];
        process(candidates,i+1,results,result,sum,target);
    }
}

(2)網上大部分人的做法

public class Solution {
    List<List<Integer>> result;
	List<Integer> solu;
	public List<List<Integer>> combinationSum(int[] candidates, int target) {
        result = new ArrayList<>();
        solu = new ArrayList<>();
        Arrays.sort(candidates);
        getCombination(candidates, target, 0, 0);
        return result;
    }
	public void getCombination(int[] candidates, int target, int sum, int level){
		if(sum>target) return;
		if(sum==target){
			result.add(new ArrayList<>(solu));
			return;
		}
		for(int i=level;i<candidates.length;i++){
			sum+=candidates[i];
			solu.add(candidates[i]);
			getCombination(candidates, target, sum, i);
			solu.remove(solu.size()-1);
			sum-=candidates[i];
		}
	}
}