對於無重複項的組合問題的遞迴思路可從以下幾個步驟入手(以陣列為例,如對其他元素排列,將元素編號放入陣列即可):
以陣列a[5]=為例,用c(5,num)表示從這5個數中選擇num個數,求其所有的情況。
首先要明確,求一組數的組合問題,元素是沒有位置要求的,即對於c(5,3)的求解和是一種情況。因此,為了防止結果的多餘項,必須保證在求解過程中,原陣列的元素位置是固定的!
1、選取乙個元素,即求解c(5,1)時,按序號從陣列中順序取出乙個元素,結果為
2、選取兩個元素,即求解c(5,2)時,先按序號從陣列中順序取出乙個元素,再在取出的元素後面的元素中選取乙個元素。設這個序號為i,則當i=5-2=3時為止(i從0開始),因為當i>3時,後面的元素不足1個。詳細如下:
第一步:a.選取 b.在中求解c(4,1);
第二步:a.選取 b.在中求解c(3,1);
第三步:a.選取 b.在中求解c(2,1);
第四步:a.選取 b.在中求解c(1,1); 的序號為3,此時結束
3、選取三個元素,即求解c(5,3)時,先按序號從陣列中順序取出乙個元素,再在取出的元素後面的元素中選取兩個元素。設這個序號為i,則當i=5-3=2是時止(i從0開始),因為當i>2時,後面的元素不足2個。
4、以此類推,即組合c(n,num)的求解過程是:固定位置後,按順序取出乙個元素,再在此元素後面的元素中取num=num-1個元素,當取出的元素個數足夠了的時候,即此時num=0時,為遞迴的出口。
程式例項如下:
/*存放輸出的陣列集合*/
private static listoutarr = new arraylist();
/*outarr內存放的數量*/
private static int index=0;
/***
* @param inarr 待組合的陣列
* @param n 表示inarr位置,如n=0則從inarr[0]-inarr[length-1]選取數字;n=1,則從inarr[1]-inarr[length-1]選取數字,length為陣列長度
* @param num 要選出數字的數量
*/public static void combnorep(int inarr,int n,int num) system.out.println();//列印陣列
}else
}} }
用一組排
好序的陣列來分析過程: 求解c(5,3),若按無重複項的方法來求解的話,會得到一下幾種情況:
對於在第0個位置,在第1個位置的情況,可表示所有的情況,和的3種情況是多餘的;
對於在第0個位置的情況,同樣可表示所有的情況,的3種情況是多餘的;
因此得出結論,去重的原則為:對於排好序的輸入陣列按無重複項組合,輸出陣列的每個位置上僅可存在每種元素的乙個,其他的去掉。
對無重複項組合的**稍作修改:
private static void combrepafterorder(int inarr,int n,int num) system.out.println();//列印陣列
}else {
for(int i=n;i<=inarr.length-num;i++) {
if(exis==null || inarr[i]!=exis) { //因為輸入陣列已經排好序,所有比較此位置上乙個元素即可
組合演算法 遞迴實現
假設在n個數中選取m 0 從n個數中選取編號最大的數,然後在剩下的n 1個數裡面選取m 1個數,直到從n m 1 個數中選取1個數。從n個數中選取編號更小的乙個數,繼續執行第一步,直到當前可選編號最大的值為m。下面是遞迴方法的實現 求從陣列a 1.n 中任選m個元素的所有組合。a 1.n 表示候選集...
Java 遞迴實現組合
需求 乙個模型中有n個狀態,每個狀態有m個選項,如果從每個狀態中選取乙個選項進行組合,總共有多少種組合。1.state類 public class state public state public string getname public void setname string mname pu...
遞迴組合演算法
遞迴組合演算法 演算法思想 對於乙個長度為m的序列,要求n個數的組合。1.從索引最小的元素遍歷到第n m個元素,將遍歷到的元素定為組合中的第乙個元素 2.判斷組合中n個元素是否已滿,如果滿了,列印該組合,如果不滿重,則擷取1中選擇的元素之後的序列,復步驟一。include include using...