Combination Sum 无序数组中找组合(每个元素可用多次)使得和为target@LeetCode

本文深入解析了组合求和问题中使用回溯与DFS的技巧,详细介绍了何时返回、递归参数及其物理意义,并通过实例展示了如何在Java中实现这一算法。文章还提供了代码实现细节,帮助开发者理解并应用到实际问题中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

典型DFS回溯,参考这篇 《递归,回溯,DFS,BFS的理解和模板》,另外这篇 http://blog.youkuaiyun.com/u011095253/article/details/9158423  就

1. 什么时候返回

2. 递归的时候传入什么样的参数(每个参数的物理意义是什么!)

也有着很精彩的分析!


package Level3;

import java.util.ArrayList;
import java.util.Arrays;


/**
 * 
 * Combination Sum
 * 
 * Given a set of candidate numbers (C) and a target number (T), find all unique
 * combinations in C where the candidate numbers sums to T.
 * 
 * The same repeated number may be chosen from C unlimited number of times.
 * 
 * Note: All numbers (including target) will be positive integers. Elements in a
 * combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤
 * … ≤ ak). The solution set must not contain duplicate combinations. For
 * example, given candidate set 2,3,6,7 and target 7, A solution set is: [7] [2,
 * 2, 3]
 * 
 */
public class S39 {

	public static void main(String[] args) {
		int[] candidates = {8,7,4,3};
		int target = 11;
		
		System.out.println(combinationSum(candidates, target));
	}

	public static ArrayList<ArrayList<Integer>> combinationSum(int[] candidates, int target) {
		ArrayList<ArrayList<Integer>> ret = new ArrayList<ArrayList<Integer>>();
		ArrayList<Integer> al = new ArrayList<Integer>();
		Arrays.sort(candidates);		// 必须先排序
		dfs(candidates, target, 0, ret, al);
		return ret;
	}
	
	public static void dfs(int[] candidates, int remain, int start, ArrayList<ArrayList<Integer>> ret, ArrayList<Integer> al){
		if(remain == 0){		// 找到一个合法解
			ret.add(new ArrayList<Integer>(al));
			return;
		}
		
		for(int i=start; i<candidates.length; i++){	// 扩展状态
			int rest = remain - candidates[i];
			if(rest < 0){	// 剪枝
				return;
			}
			al.add(candidates[i]);		// 执行扩展动作
			dfs(candidates, rest, i, ret, al);
			al.remove(al.size()-1);		// 撤销动作
		}
	}
	
}


Again:

public class Solution {
    public ArrayList<ArrayList<Integer>> combinationSum(int[] candidates, int target) {
        ArrayList<ArrayList<Integer>> ret = new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> al = new ArrayList<Integer>();
        Arrays.sort(candidates);
        dfs(candidates, target, 0, al, ret);
        return ret;
    }
    
    public void dfs(int[] cands, int target, int pos, ArrayList<Integer> al, ArrayList<ArrayList<Integer>> ret){
        if(target < 0){
            return;
        }
        if(target == 0){
            ret.add(new ArrayList<Integer>(al));
            return;
        }
        
        for(int i=pos; i<cands.length; i++){
            al.add(cands[i]);
            dfs(cands, target-cands[i], i, al, ret);
            al.remove(al.size()-1);
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值