1. 程式人生 > >演算法--中興面試:輸入兩個整數 n 和 m,從數列1,2,3.......n 中隨意取幾個數, 使其和等於 m

演算法--中興面試:輸入兩個整數 n 和 m,從數列1,2,3.......n 中隨意取幾個數, 使其和等於 m

Q題目

程式設計求解

輸入兩個整數 n 和 m,從數列1,2,3…….n 中隨意取幾個數, 使其和等於 m ,要求將其中所有的可能組合列出來.

Answer解法

這道題就是一道典型的動態規劃問題了,思路和揹包問題差不多,m就相當於揹包能容納的重量了,就是從右往左校驗,通過m,以及m-n進行下一次計算。

2.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,遞迴下去

當前是 : printList( m , n )

遞迴下一層是 : printList( m , n-1 ) 和 printList( m-n , n-1 )

printList(m,n)=printList(m,n1)+printList(mn,n1)

終止條件:n<=0,以及m<0(m<0說明在上一次遞迴呼叫是減的n,結果減多了,所以為負),m==0時候說明正好找到,列印

2.2程式碼實現

package 中興面試;

import java.util.ArrayList;
import java.util.List;

/**
 * 2010 年中興面試題 程式設計求解: 輸入兩個整數 n 和 m,從數列1,2,3.......n 中隨意取幾個數, 使其和等於 m
 * ,要求將其中所有的可能組合列出來.
 */
public class Test { public static void main(String[] args) { int n = 7; int m = 8; List<Integer> list = new ArrayList<>(); // 1.首先判斷,如果n>m,則n中大於m的數不可能參與組合,此時置n = m; int up = n > m ? m : n; printList(m, up, list); } /** * * @param
m * 要求滿足的和sum * @param n * 取數的範圍scope * @param list * 每一種滿足條件的組合 */
public static void printList(int m, int n, List<Integer> list) { // m=0時,即揹包剛好裝滿,列印並退出 if (m == 0) { System.out.println(list); return; } // 根據題意,可知m和n必須為正整數,所以m和n為負數,或n=0時,直接退出 if (n <= 0 || m < 0) { return; } // 拿到上一次計算的結果list List<Integer> list1 = new ArrayList<Integer>(list); // n沒有加入 printList(m, n - 1, list); // n加入 list1.add(n); printList(m - n, n - 1, list1); } }

測試結果:

這裡寫圖片描述