1. 程式人生 > >《已測試通過》輸入兩個整數 n 和 m,從數列1,2,3.......n 中隨意取幾個數,使其和等於m ,要求將其中所有的可能組合列出來,並且按每個組合的字典序排列輸出,每行輸出一種組合

《已測試通過》輸入兩個整數 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();
        }
    }
}