集合中元素組合的所有可能
:集合中的數據不重複,需要窮舉,可以採用遞歸+回溯
的方法;分析回溯算法,常常需要畫圖來幫助我們理清思路和尋找邊界問題:遞歸什麼時候截止
,什麼時候可以進行剪枝
package BDyNamicProgramming;
import java.util.ArrayList;
import java.util.List;
/**
* @Author Zhou jian
* @Date 2020 ${month} 2020/4/25 0025 14:18
*/
public class Problem77 {
/**
* 返回1,2,3.....n數中,組成k個數的所有可能情況
* @param n
* @param k
* @return
*/
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> rs = new ArrayList<>();
List<Integer> path = new ArrayList<>();
fun(n,k,rs,path,0);
return rs;
}
/**
*
* @param n 待取的數
* @param k 還剩取的數的個數 (若k==0)則說明找到一個組合
* @param rs 存取最終存的結果
* @param path 存儲遍歷的過程中的路徑
* @param begin 搜索的起始路徑(這很關鍵
* 組合(元素可以重複 元素不可以重複)
*
* 排列(
*/
public void fun(int n,int k,List<List<Integer>> rs,List<Integer> path,int begin){
//組成一個組合
if(k==0){
rs.add(new ArrayList<>(path));
return;
}
//進行遞歸查找:查找的位置從begin開始
for(int i=begin;i<n;i++){
//放這裏提前一些,不用遞歸進去判斷
//意思是,就算將i......n這 n - i + 1個數字都選到vec中,都不夠k長度,則不用繼續遞歸了
if(k -path.size() > n - i + 1)
return;
path.add(i+1);
//接下來查找的位置從其後面的一個位置開始查找(若可以取重複元素則可以從自身開始 其實位置爲i)
fun(n,k-1,rs,path,i+1);
//進行回溯
path.remove((Object)(i+1));
}
}
}