《已测试通过》输入两个整数 n 和 m,从数列1,2,3.......n 中随意取几个数,使其和等于m ,要求将其中所有的可能组合列出来,并且按每个组合的字典序排列输出,每行输出一种组合

参考网上很多,玛德都不测试的吗?就贴出来了?浪费时间。互联网精神在哪!!!

import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Scanner;

/**
 * [编程题] 求和
 * 输入两个整数 n 和 m,从数列1,2,3.......n 中随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来
 * 输入描述:
 * 每个测试输入包含2个整数,n和m
 *
 * 输出描述:
 * 按每个组合的字典序排列输出,每行输出一种组合
 *
 * 输入例子1:
 * 5 5
 *
 * 输出例子1:
 * 1 4
 * 2 3
 * 5//注意这里是一个数的情况
 */

/**
 * 分析:分治的思想。可以把问题(m,n)拆分(m - n, n -1)和(m, n - 1)。
 * 1.首先判断,如果n>m,则n中大于m的数不可能参与组合,此时置n = m;
 * 2.将最大数n加入且n == m,则满足条件,输出;
 * 3.将n分两种情况求解,
 * (1)n没有加入,取n = n - 1; m = m;递归下去;
 * (2)n加入,取n = n - 1, m = m - n,递归下去
 */
public class ListAllPossibleCombinationsWhichSumIsM {
    
    private static LinkedList<Integer> list = new LinkedList<>();
    private static ArrayList<int[]> arrayList = new ArrayList<>();
    
    public static void findSum(int n, int m) {
        if (n < 1 || m < 1)
            return;
        if (m < n)
            n = m;//这里实际上完成了  n =  m-n  是从递归一开始累计的,不单单指这层
        if (m == n) {
            int[] temp = new int[list.size()+1];
            temp[0] = m;//最小的先放进去
            int index = 0;
            for (int i = list.size()-1; i >= 0 ; i--){//倒着装进去 因为我们是从n开始的,也就是从大到小的递归,那么list中实际上是倒序
                temp[++index] = list.get(i);
            }

            arrayList.add(temp);
        }

        list.addLast(n);
        findSum(n - 1,m - n);//取了最后一个数,那么和m就减去最后一个数n   m-n 
        list.removeLast();
        findSum( n - 1,m);//最后一个数不可取   n没有加入,取n=n-1,m=m
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        findSum(n,m);

        arrayList.sort(new Comparator<int[]>() {//字典序排序,先按照第一位,再按照第二位。。。
            @Override
            public int compare(int[] o1, int[] o2) {
                if (o1[0] > o2[0]){
                    return 1;
                }else if(o1[0] < o2[0]){
                    return -1;
                }else {
                    if (o1[1] > o2[1]){
                        return 1;
                    }else if(o1[1] < o2[1]){
                        return -1;
                    }else{
                        return 0;
                    }
                }
            }
        });
        for (int[] ints : arrayList) {
            for (int i = 0; i < ints.length; i++) {
                System.out.print(ints[i]);
                if (i != ints.length-1)
                    System.out.print(" ");
            }
            System.out.println();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_38450840/article/details/81978818