Java求解所有的可能组合列出来,输入两个整数n和m,从数列1,2,3,……n中随意取几个数,使其和等于m。

本文介绍了一种使用Java实现的背包动态规划算法,用于解决从数列中选取若干数使其和等于目标值的问题。通过递归方法,文章详细阐述了如何找出所有可能的组合,并提供了完整的代码示例。

Java求解,输入两个整数n和m,从数列1,2,3,……n中随意取几个数,使其和等于m。要求将所有的可能组合列出来(背包动态规划问题求解)

输入两个整数n和m,从数列1,2,3,……n中随意取几个数,使其和等于m。要求将所有的可能组合列出来。

之前看到有同学写该问题的Java版本,但是照着运行了一下,发现还是存在问题,经过自己的查资料研究,特写出Java版本的正确解答;

该问题初始大概的想法就是:

1)第一种情况,含有n,则递归调用函数求 从1,2,3   到n-1取任意几个数,组成m-n;

2)第二种情况,不含n,则递归调用函数求从1,2,3 到n取任意几个数,组成m;

有了问题的大概想法后,则需要判断特殊条件:

1)如果n大于m,则大于m的数都不能抽取,该问题化为从1,2,3 到m抽取任意几个数组成m;

2)边界值问题,何时为递归的结束条件,分一下三种情况:第一种:m==0&&n>=0,此时应该结束,打印结果,返回;第二种情况:n>=1&&m==1,则直接从n中取1,,压入linkedlist中,打印结果,再pop出1,返回; 第三种情况:n==1&&m>1,则直接返回,该中组合不能构成m;
 

import java.util.LinkedList;

/**
 * @author yuchen
 * @version 1.0
 * @date 2020-05-20 15:21
 */
public class N {

    private static LinkedList<Integer> list=new LinkedList<Integer>();

    public static void main(String[] args) {

        int n = 6;
        int m = 10;

        findSum(m,n);

    }

    public static void findSum(int sum,int n){

        //数组有序 m=0 n的范围是1-n所以 这种情况 直接不存在 打印空集合
        if(sum == 0 && n >= 0){
            myPrint();
            return;
        }

        //和是1 n>=1 因为1-n 所以把1放到集合里 打印出来后 再移除
        if(sum == 1 && n >= 1){
            list.push(1);
            myPrint();
            list.pop();
            return;
        }

        //最小元素就是1 sum的和>1 所以没有
        if(sum > 1 && n == 1 ){
            return;
        }

        if(sum >= n){
            //sum包含n的情况 剩下的集合中 计算出sum = sum-n的情况
            list.push(n);
            findSum(sum - n ,n-1);
            list.pop();

            //sum不包含n的情况 即sum > n
            findSum(sum ,n-1);
        }else{
            //sum < n的情况
            findSum(sum ,sum);
        }

       return;

    }

    public static void myPrint(){

        for(int i=0;i<list.size();i++){
            System.out.print(list.get(i));
        }
        System.out.println();
    }




}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值