CombinationSum 问题

组合求和问题

输入:一个无序数组,一个目标和
输出:数组中目标和的组合
要求:结果中不含重复组合
用例:[2,3,6,7],7 ===> [ [7] [2,2,3] ]


分析

这个也没啥分析的。从一头开始一个个加进去,看还剩多少,再加。直到剩的为0或者小于0为止。

思路

回溯法。
关键在于回溯。
再加上迭代。就ok

代码

package day_7;
// 这是要写一个迭代。
// 或者是用 dfs(Deep First Search)
// 无奈 迭代 你用的很差 从这一个算法开始学一下吧
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CombinationSum {
    public List<List<Integer>> combinationSum(int[] candidates, int target){
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        if(candidates==null || candidates.length==0)
            return res;
        Arrays.sort(candidates); // 先排升序
        helper(candidates,target,0,new ArrayList<Integer>(),res);
        return res;
    }

    private void helper(int[] candidates,int target, int start, ArrayList<Integer> item, List<List<Integer>> res){
        if(target == 0){
            // 这时候做一步去重
            if(!res.contains(item)) res.add( new ArrayList<Integer>(item));  // 这里注意写法。要写 new array list(item) 因为这里的 item 在后面回溯还要用。 
// 相当于把当前的Item 重新申请了空间,复制了一份。 不这样做的话,最终的 item 指向的空间对应的数是空的。因为后面有回溯的步骤。
            return;
        }

        if(target < 0) return; // 这是迭代的结束条件,很重要

        //剩下的就是 target>0 的情况
        for( int i=start ; i<candidates.length; i++){
            item.add(candidates[i]);
            helper(candidates,target-candidates[i],i,item,res);
            item.remove(item.size()-1);  // 这是回溯法很重要的 一步 回溯。即每次删除最后的一个来看
        }

    }

    public static void main(String[] args){
        int a[] = {2,3,5};
        CombinationSum c = new CombinationSum();
        System.out.println(c.combinationSum(a,8));
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容