combination sum总结(java)

程序是别人的,我几乎没动。惊叹其运行速度,转载一下~

原地址:https://www.jianshu.com/p/42211be17acb

我一开始的思路是用取余,余数小于被除数就说明多除了一次,应该往后退一步,一半递归一半循环,看了他的思路,发现我递归到后面数非常小了,用除法还不如用减法,全都用减法的,清晰好用。

分析:

  1. 使用Arrays.sort(candidates);先排序
  2. 参数targetlist每加入一个数字元素时,值减少,通过对target的判断,选择操作种类
  3. 深度优先遍历,当target始终大于0时,会一直进行搜索,不断跳入新的递归方法,直到target小于等于0或数组到达尾部
  4. 当搜索到达尾部时,通过不断去除list最后元素,for循环进入到下一个 i 的深度遍历,来达到全部组合的遍历
  5. flag用于跳出循环,增加效率,排序后的数组呈升序,当返回此路不通时,for循环后面更大的数也将返回false,可以直接跳出

程序如下:

class Solution {
public List> combinationSum(int[] candidates, int target) {
	List> result = new ArrayList<>();
	List list = new ArrayList<>();
	
	Arrays.sort(candidates);
	combinationSumHelp(candidates,result,list,target,0);
	return result;
}

public boolean combinationSumHelp(int[] candidates,List> result,List list,int target,int start){
	if(target<0){
		return false;
	}else if(target==0){
		List temp = new ArrayList(list);
		result.add(temp);
		return false;
	}else{
		for(int i = start; i < candidates.length ; i++){
			list.add(candidates[i]);
			boolean flag = combinationSumHelp(candidates,result,list,target-candidates[i],i);
			list.remove(list.size()-1);
			if(!flag){
				break;
			}
		}
}
	return true;
}
}

总结

  • 递归方法总是需要大量优化,递归的位置也尤为重要
  • 深度优先遍历,其实就是获取所有解的过程,在其中分辨需要的解进行操作
  • 对于可变对象的操作需要谨慎,为其重新分配空间可以使其变为不可变对象(没有被增删改)
  • 尽量不使用集合来处理问题是数组类题目提升效率的基本操作

combination sum总结(java)_第1张图片

你可能感兴趣的:(learning)