1. 程式人生 > >Leetcode學習筆記 39 組合總和

Leetcode學習筆記 39 組合總和

轉載自:https://www.unclegem.cn/2018/09/10/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]
]

解題思路:

回溯:只要當前總和值小於目標值,就一直添加當前元素,新增到大於目標值,則回退到上一個狀態去尋找下一個元素,其中的start引數是為了防止出現重複答案如[2,2,3]和[3,2,2]。

	public int sum = 0;
	public List<List<Integer>> res = new ArrayList<>();
	public List<List<Integer>> combinationSum(int[] c, int tar) {
		res.clear();
		sum = 0;
		Arrays.sort(c);
		List<Integer> list = new ArrayList<Integer>();
		recycle(c, tar, list, sum, 0);
		return res;
	}
	
	public void recycle(int[] c, int tar, List<Integer> list, int sum, int start) {//start記錄當前元素的位置
		if(sum == tar) {
			res.add(new ArrayList<Integer>(list));
			return;
		}
		for(int i = start; i< c.length; i++) {
			if(sum < tar && (sum + c[i]) <= tar) {
				list.add(c[i]);
				sum += c[i];
				recycle(c, tar, list, sum, i);//遞迴呼叫,其中的i引數是為了防止出現重複答案如[2,2,3]和[3,2,2]。
				start ++;
				sum -= c[i];//開始回溯到上一個狀態
				list.remove(list.size() - 1);
			}
		}
	}

leetcode戰勝30%左右,應該還有時間更少的解法,但對我來說這可能是一種比較容易想到的解法