演算法 排列組合問題

2021-09-26 06:37:11 字數 1821 閱讀 3103

從m個數裡面選n個(m >= n)

全部用到 棧的儲存結構 + 遞迴方法

用棧儲存選取的那n個數,選取就push,換乙個就pop再push

遞迴方法:要選取n個數,已經選取了k個,k == n時表示一種組合結果完成

,選擇乙個再之後遞迴(k+1)

這是最簡單的問題,選擇n個數,每個數有m個選擇

每次選擇時只需要迴圈這m個數:

push()

遞迴(k+1)

pop()

迴圈m個數,就是把這位上的數m次選擇都做了一遍

/**

* @author: changsiteng

* @description:

* @param n: 選取n個數

* @param k: 已經選取了k個數

* @param numbers: 存放m個選擇的陣列

* @param list: 存放所有選擇的list

* @param stack: 存放已經選取的數的棧結構

* @return: void

*/public void rank(int n, int k, int numbers, arraylist list, stack stack)

// 遍歷number,做m次選擇

for (int number : numbers)

}

依舊使用遞迴和棧資料結構

和rank1不同的是:

選擇n個數,每個數的選擇不再是單純的m個選擇,而是未被選擇過的m-k個數

因此使用乙個used陣列標記是否已被訪問,1表示已經被使用,0表示未被使用

/**

* @author: changsiteng

* @description:

* @param number:

* @param used:

* @param n: 需要選擇n個數

* @param k: 已經選擇了k個

* @param list:

* @param stack:

* @return: void

*/public void rank(int number, int used, int n, int k, list list, stack stack)

for (int i = 0; i < number.length; i++)

}}

同樣和rank1做對比:

選擇n個數,

如果是mn每個數的選擇是單純的m個選擇

如果是amn則是從i=0開始遍歷,所有未選擇過的數作為選擇

如果是cmn則是從當前選擇的i開始遍歷,之前的i都不作為選擇,也是如此做法遍歷的i都是未選擇過的,因此也不需要陣列

/**

* @author: changsiteng

* @description:

* @param number:

* @param n: 需要選擇n個數

* @param k: 當前選擇了k個數

* @param index: 當前選擇的第k個數的下標時(最大下標,初始化為-1)

* @param list:

* @param stack:

* @return: void

*/public void rank(int number, int n, int k, int index, list list, stack stack)

for (int i = index + 1 ; i < number.length; i++)

}

演算法 排列組合

a m,n n n m 從 n 個數中取 m 個有前後順序的數列 有 a m,n 種方式 c m,n n n m m a m,n m 從 n 個數中取 m 個無前後順序的數列 有 c m,n 種方式 性質 c m,n c n m,n c r,n 1 c r 1,n c r,n 楊輝三角性質 c 0,...

排列組合問題

若有一串字母abc,進行全排列,有六種方法,3的階層,321,為什麼是這樣呢,我們根據 看思路 這之間會涉及遞迴,回溯 將abc看成陣列,a 0 a,a 1 b,a 2 c 下文中用a0代替a,a1代替b,a2代替c 排列的過程就是交換位置的過程 1 先對a進行交換 即k 0時 a0和a0自己交換 ...

排列組合問題

基本的排列組合問題,就是高中數學的內容,怎麼用程式語言輸出所有排列呢?我們手寫的過程,它應該是乙個遞迴的過程,而不適合用for wihle迴圈。如果資料結構學的紮實,可以發現這是乙個樹結構,遍歷所有的葉子節點就能夠得到全排列。說到遞迴,應該向大家隆重介紹一下數學歸納法的思想,應為都有乙個問題規模n。...