面试算法81:允许重复选择元素的组合

题目

给定一个没有重复数字的正整数集合,请找出所有元素之和等于某个给定值的所有组合。同一个数字可以在组合中出现任意次。例如,输入整数集合[2,3,5],元素之和等于8的组合有3个,分别是[2,2,2,2]、[2,3,3]和[3,5]。

分析

能够用回溯法解决的问题都能够分成若干步来解决,每一步都面临若干选择。对于从集合中选取数字组成组合的问题而言,集合中有多少个数字,解决这个问题就需要多少步。每一步都从集合中取出一个下标为i的数字,此时面临两个选择。一个选择是跳过这个数字不将该数字添加到组合中,那么这一步实际上什么都不做,接下来处理下标为i+1的数字。另一个选择是将数字添加到组合中,由于一个数字可以重复在组合中出现,也就是说,下一步可能再次选择同一个数字,因此下一步仍然处理下标为i的数字。

java 复制代码
public class Test {
    public static void main(String[] args) {
        int[] nums = {2, 3, 5};
        List<List<Integer>> result = combinationSum(nums, 8);
        for (List<Integer> item : result) {
            System.out.println(item);
        }
    }

    public static List<List<Integer>> combinationSum(int[] nums, int target) {
        List<List<Integer>> result = new LinkedList<>();
        LinkedList<Integer> combination = new LinkedList<>();
        helper(nums, target, 0, combination, result);

        return result;
    }

    private static void helper(int[] nums, int target, int i, LinkedList<Integer> combination,
        List<List<Integer>> result) {
        if (target == 0) {
            result.add(new LinkedList<>(combination));
        }
        else if (target > 0 && i < nums.length) {
            helper(nums, target, i + 1, combination, result);

            combination.add(nums[i]);
            helper(nums, target - nums[i], i, combination, result);
            combination.removeLast();
        }
    }
}
相关推荐
boooooooom12 小时前
Pinia必学4大核心API:$patch/$reset/$subscribe/$onAction,用法封神!
javascript·vue.js·面试
生锈的键盘12 小时前
推荐算法实践:交叉特征的理解
算法
试着12 小时前
【huawei】机考整理
学习·华为·面试·机试
小龙报12 小时前
【51单片机】从 0 到 1 玩转 51 蜂鸣器:分清有源无源,轻松驱动它奏响新年旋律
c语言·数据结构·c++·stm32·单片机·嵌入式硬件·51单片机
dllxhcjla12 小时前
数据结构和算法
数据结构
乌萨奇也要立志学C++12 小时前
【洛谷】BFS 求解最短路:从马的遍历到迷宫问题的实战解析
算法·宽度优先
石去皿12 小时前
【嵌入式就业6】计算机组成原理与操作系统核心机制:夯实底层基础
c++·面试·嵌入式
老鼠只爱大米12 小时前
LeetCode经典算法面试题 #46:全排列(回溯、交换、剪枝等五种实现方案详细解析)
算法·leetcode·剪枝·回溯·全排列·stj算法
Dovis(誓平步青云)12 小时前
《滑动窗口算法:从 “暴力遍历” 到 “线性高效” 的思维跃迁》
运维·服务器·数据库·算法
闻哥13 小时前
Kafka高吞吐量核心揭秘:四大技术架构深度解析
java·jvm·面试·kafka·rabbitmq·springboot