java实现组合总和

题目:

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有不同组合 ,并以列表形式返回。你可以按任意顺序返回这些组合。candidates 中的同一个数字可以无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。 对于给定的输入,保证和为 target 的不同组合数少于 150 个。

示例1:

示例2:

示例3:

思路:

有三个方法:main方法,combinationSum()方法,dfs()方法。

  1. combinationSum()方法:

两个参数:

  • int[] candidates:输入的数组;

  • target:目标值;

返回值:

是List<List<Integer>>类型,表示返回的是一个二维数组,数组里面元素都是Integer整型类型

我们在该方法中声明两个数组,以便后面递归调用dfs()方法传入参数

  1. dfs()方法:

五个参数:

  • candidates:输入的数组

  • target:目标值

  • res:返回的结果

  • combine:返回结果的子结果

  • index:数组下标

  • 我们递归时要注意终止(出口)条件,当数组下标index等于数组长度时,即直接retrun

  • 当传入的target==0,即表示已经找到可行解,将combine添加至res中进行输出

  • 当index=0递归完成后,将index+1继续进行递归

  1. main方法:

  • 用键盘输入,依次输入数组和目标值traget

  • 调用combinationSum(),传入实参后输出结果

package Lq_算法练习;

import java.util.ArrayDeque;
import java.util.Scanner;

public class Demo_组合总和 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String str = in.nextLine();//输入数组
        int target = in.nextInt();//输入目标值
        String[] strArray = str.split(",");//输入的数组用','来分隔
        int[] candidates = new int[strArray.length];//声明一个数组长度为strArray.length的数组
        for (int i = 0; i < candidates.length; i++) {
            candidates[i] = Integer.parseInt(strArray[i]);//将整型数据Integer转换为基本数据类型int
        }
        //Integer本身是int类型的封装类.意思就是把一个int 类型的数据封装成对象;
        //List<Integer>表明List中封装的必须是一个整型
        List<List<Integer>> res = combinationSum(candidates, target);
        System.out.println(res);
    }
//返回值是一个List<List<Integer>>类型,表示返回的是一个二维数组,数组里面元素都是Integer整型类型
    public static List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        List<Integer> combine = new ArrayList<>();
        // index=0,从第一个元素开始递归
        dfs(candidates, target, res, combine, 0);
        return res;
    }
/*
 * candidates:输入的数组
 * target:目标值
 * res:返回的结果
 * combine:返回结果的子结果
 * index:数组下标
 */
    public static void dfs(int[] candidates, int target, List<List<Integer>> res, List<Integer> combine, int index) {
        // index从0开始累加,当index等于数组长度时,表示已经对前index-1个元素(即全部元素)完成递归
        if (index == candidates.length) {
            //递归终止条件
            return;
        }
        // 每一次递归,当传入的target==0,即表示已经找到可行解,将combine添加至res中进行输出
        if (target == 0) {
            res.add(new ArrayList<Integer>(combine));
            return;
        }
        // index每次加1进行递归
        dfs(candidates, target, res, combine, index + 1);
        // 对元素进行判断,若元素小于target,添加元素至combine中
        if (target - candidates[index] >= 0) {
            combine.add(candidates[index]);
            // 改变target值,再次递归,因为每个元素可以被使用多次,所以index不变
            //这里的traget就等于其本身减去上面已经添加到combine数组中的元素
            dfs(candidates, target - candidates[index], res, combine, index);
            // combine要存储每一次的可能结果,所以每次都要进行移除操作,让combine为空,方便下一次操作
            combine.remove(combine.size() - 1);//移除数组中最后一个元素,这里只有一个元素,移除便可
        }
    }
}

运行结果示例:

示例1:

示例2:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值