【微軟谷歌面試100題--【21】從1-n中找出和爲m的所有組合

第21題:

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

看到這樣的題目,我蒙圈了,不知道從何處下手。通過在網上搜集資料,自己終於搞定了。

先看下思路:

給定了n和m;

1.要判斷n*(n+1)/2m的關係

如果n*(n+1)/2>m 有戲,我們可以繼續往下做,

如果n*(n+1)/2<m  沒戲了,因爲1,2,...n所有的數加起來還沒有m大呢。所以直接退出。

2.然後就是循環找數咯

循環的起始條件肯定是從 i=1開始,但是到哪裏結束呢? 循環的條件是:i<n&&i<m/2 ,這個地方就是重點了,i<n 是肯定的要有的,關鍵是後面 i<m/2;因爲如果i >=m/2 ,那麼比 i大的數在與i求和,肯定就大與m了。

3.遞歸求解


代碼:

public class Algorithm21_0 {
	static void getAllComp(int n,int m){
		String pre = m+"=";
		int theMax = (1+n)*n/2;
		if(theMax<m){
			System.out.println("不存在該數!");
		}else{
			for(int i=1;i<n&&i<=m/2;i++){
				//從1開始計數,打印出兩個數的組合,並且兩數不相等
				if(i != m-i&&((m-i)<=n)){
					System.out.println("here:"+pre+i+"+"+(m-i));
					//continue;
				}
				//調用遞歸,繼續求得大於2個數的組合
				getTheResult(m-i,pre+i,i,n);
			}
		}
	}
	//調用遞歸,繼續求得大於2個數的組合,j爲組合中已用過的數,所以取大於該數的。
	static void getTheResult(int m,String pre,int j,int n){
		for(int i=j+1;i<n&&i<=m/2;i++){
			if(i != m-i&&((m-i)<=n))
				System.out.println("fuck:"+pre+"+"+i+"+"+(m-i));
			getTheResult(m-i,pre+"+"+i,i,n);
		}
	}
	
	public static void main(String[] args) {
		getAllComp(10,11);
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章