LeetCode039——组合总和

我的LeetCode代码仓:https://github.com/617076674/LeetCode

原题链接:https://leetcode-cn.com/problems/combination-sum/description/

题目描述:

LeetCode039——组合总和_第1张图片

知识点:回溯、递归

思路:用回溯法寻找所有可能的组合

本题要求的是candidates数组中所有可以使数字和为target的组合,我们需要穷尽所有的candidates数组可能产生的组合,因此很明显的,我们需要用回溯算法来解决问题。在解决问题的过程中有以下几个注意点:

(1)在Solution类中新建一个List>类型的私有成员变量listList用以保存结果,可以防止在递归函数中重复传递该值。

(2)本题要求的是组合,并不是排列,我们假设每一次加入到我们list中的元素都大于等于list中最后一个元素,这样可以防止出现重复的组合。因此,我们在递归之前要先对candidates数组进行排序。

(3)我们的递归函数private void combinationSum(int[] candidates, int target, List list, int sum)的定义如下:

在candidates数组中寻找和为target的组合,目前我们list中存放的数据和为sum,我们将要在candidates中寻找下一个存入list的数字。

递归终止条件

当sum的值大于等于target的值时,由于题目限定了所有数字都是正整数,如果我们再向list中添加元素,sum必将越来越大,不可能等于target,我们直接返回。但在返回之前我们需要判断sum是否与target相等,如果相等,我们保存list集合进listList中。

注意这里不能使用listList.add(list),而应该使用listList.add(new ArrayList<>(list))。因为list是一个引用,在回溯过程中,其指向的集合是在不断改变的,我们要记录的是递归到底时list中存储的数据,因此我们需要根据list来新建一个ArrayList来保存。

递归过程

如果list中没有任何元素,其新增的下一个元素可以是candidates中的任意一个元素。注意list集合的手动回溯过程

如果list中有元素,其新增的下一个元素必须等于等于list中最后一个元素。注意list集合的手动回溯过程

关于时间复杂度,一开始我们对candidates数组进行了排序,该过程的时间复杂度是O(nlogn),其中n为candidates数组的长度。而整个递归过程的时间复杂度,如果考虑最坏情况,即target为candidates中所有元素之和,其时间复杂度是O(n ^ n)。因此总的时间复杂度应该是O(n ^ n)。而空间复杂度就是递归深度,最坏情况应该是递归target次,因此空间复杂度为O(target)级别。

JAVA代码:

public class Solution {
	
	private List> listList;

	public List> combinationSum(int[] candidates, int target) {
		listList = new ArrayList<>();
		Arrays.sort(candidates);
		combinationSum(candidates, target, new ArrayList<>(), 0);
		return listList;
	}
	
	private void combinationSum(int[] candidates, int target, List list, int sum) {
		if(sum >= target) {
			if(sum == target) {
				listList.add(new ArrayList<>(list));
			}
			return;
		}
		if(list.size() == 0) {
			for (int i = 0; i < candidates.length; i++) {
				list.add(candidates[i]);
				combinationSum(candidates, target, list, sum + candidates[i]);
				list.remove(list.size() - 1);
			}
		}else {
			for (int i = 0; i < candidates.length; i++) {
				if(candidates[i] >= list.get(list.size() - 1)) {
					list.add(candidates[i]);
					combinationSum(candidates, target, list, sum + candidates[i]);
					list.remove(list.size() - 1);
				}
			}
		}
	}	
}

LeetCode解题报告:

LeetCode039——组合总和_第2张图片

 

你可能感兴趣的:(LeetCode题解)