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<List<Integer>> combinationSum(int[] candidates, int target) {
	List<List<Integer>> result = new ArrayList<>();
	List<Integer> list = new ArrayList<>();
	
	Arrays.sort(candidates);
	combinationSumHelp(candidates,result,list,target,0);
	return result;
}

public boolean combinationSumHelp(int[] candidates,List<List<Integer>> result,List<Integer> list,int target,int start){
	if(target<0){
		return false;
	}else if(target==0){
		List<Integer> temp = new ArrayList<Integer>(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;
}
}

总结

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值