其他分享
首页 > 其他分享> > 剑指offer81:允许重复选择元素的组合

剑指offer81:允许重复选择元素的组合

作者:互联网

题目:
给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。
candidates 中的数字可以无限制重复被选取。如果至少一个所选数字数量不同,则两种组合是唯一的。
对于给定的输入,保证和为 target 的唯一组合数少于 150 个。
1.输入: candidates = [2,3,6,7], target = 7
输出: [[7],[2,2,3]]
2.输入: candidates = [2,3,5], target = 8
输出: [[2,2,2,2],[2,3,3],[3,5]]
3.输入: candidates = [1], target = 2
输出: [[1,1]]
分析:
该题和之前的79和80相比大同小异,最主要的不同点在于当选择将数组nums下标为i的数字添加到组合combination中之后,由于nums[i]这个数字可能在组合中重复出现,因此递归调用函数helper时第三个参数传入的指仍然是i,这个参数没有变化,下一步仍然处理数组nums的下标为i的数字。
该题target是组合combination中元素之和的目标值,每当在组合中添加一个数字时,就从target中减去这个数字,当target等于0的时候,组合中的所有元素之和正好等于target,因此也就找到一个符合条件的组合。
当使用回溯法解决问题时尽可能剪枝来优化时间效率,因为题目中明确指出数组中的所有数字都是正整数,因此当组合中已有数字和已经大于目标值的时候(target<0)就没必要考虑数组中还没有处理的数字,因此再在组合中添加任意正整数元素之后和会更大,一定找不到新的符合条件的组合。
代码:

import java.util.LinkedList;
import java.util.List;

public class CombinationSum {
    public static void main(String[] args) {
        CombinationSum combinationSum = new CombinationSum();
        int[] nums = {2,3,5};
        List<List<Integer>> lists = combinationSum.combinationSum(nums, 8);
        System.out.println(lists);
    }
    public List<List<Integer>> combinationSum(int[] nums, int target) {
        List<List<Integer>> result = new LinkedList<>();
        LinkedList<Integer> combination = new LinkedList<>();
        helper(nums,target,0,result,combination);
        return result;
    }

    private void helper(int[] nums, int target, int i, List<List<Integer>> result, LinkedList<Integer> combination) {
        if (target == 0){
            result.add(new LinkedList<>(combination));
            //target>0的作用是剪枝,减少不必要的递归,具体分析中有写。
        }else if (target >0 && i < nums.length){
            helper(nums,target,i+1,result,combination);
            combination.add(nums[i]);
//            由于一个数字可以重复在组合中出现,也就是说下一步可能选择同一个数字,因此下一步仍然处理下标为i的数字。
            helper(nums,target-nums[i],i,result,combination);
            combination.removeLast();
        }
    }
}

在这里插入图片描述

标签:target,combination,nums,重复,元素,offer81,组合,result,数字
来源: https://blog.csdn.net/Jiaodaqiaobiluo/article/details/122274531