N個小球放進M個盒子算法

N個小球放入M個盒子共有多少種方法,並輸出的算法設計:java

算法思路1 :暴力填充盒子算法

每一個小球均可能放入M個盒子的任意一個,因此直接根據小球個數作遞歸便可,而後將存儲放入hash中排重bash

//TODO優化

算法思路2 :遞歸填充盒子this

即,每層遞歸僅考慮一個盒子放幾個球,剩下的球交給下一個遞歸。設計

好比第一個盒子裏放N個球,則剩下的都是0個;第一個盒子放n-1個球,問題就變成了1個球與M-1個盒子的問題...直到第一個盒子放0個球,問題變成了N個球與M個盒子的問題。code

遞歸的入口是第1個盒子,那麼遞歸的出口在哪?天然是最後一個盒子。當盒子只剩一個時候便不向下遞歸,還剩多少小球就全放進盒子裏。遞歸

 

遞歸僞代碼以下:hash

public void everyBox(int boxes , int balls ,String oneResult ){

    if (boxes ==1){                       //遞歸出口

        thisResult = oneResult+balls   

        return

    }

    for( i=balls ; i >=0 ; i -- ){

        thisResult  = oneResult + (String) i

        everyBox(boxes-1 , balls-i , thisResult)  //遞歸 

    }

}

算法2優化:it

上述遞歸只有一個出口,就是隻剩一個box時候。不過這個程序還有一個能夠優化的出口:在balls等於0的時候。假設還剩餘X個盒子沒有進行遞歸,而這時候剩餘ball是0,便不用遞歸了,直接輸出X個0便可。當盒子數>>小球數時候,能夠極大減小遞歸的層次,提升代碼效率。

優化後的java示例代碼以下,因爲要輸出就直接systemout了:

public class NballMbox {
	
	public static void main(String[] args) {
		NballMbox nm = new NballMbox();
		nm.iterator(4, 2, "");
	}
	
	public void iterator(int balls , int boxes , String s){
		//ball =0 直接結算
		if(balls == 0){
			for(int i = 0 ;i< boxes ;i++)
				s = s+ 0;
			System.out.println(s.toString());
			return;
		}
		for(int i =balls;i >=0;i--){
			String s1 = s+i;
			if(boxes == 1){
				System.out.println(s1.toString());
				return;
			}
			else
				this.iterator(balls-i, boxes-1, s1);
		}
	}
}
相關文章
相關標籤/搜索