dfs求排列以及組合

2021-10-09 21:25:29 字數 1222 閱讀 2623

排列比較簡單,設定乙個vis陣列判斷每個數是否用過,然後for迴圈進行判定並且dfs就行,主要是注意乙個數用完之後dfs進行標記vis,dfs完之後換乙個數,就要把這個數的vis記錄抹去,代表下次還能用

組合其實卡了我挺久,因為組合不像排列那樣乙個數可以出現在所有位置並且只要判vis就行。這裡的組合借鑑的是別人的思路。用乙個陣列來儲存已經放入的值,top指標進行覆蓋或者新增,depth作為原陣列的深度進行迭代,所以一旦乙個數在前面位置出現,他就永遠只能在那個位置出現,等到包含這個數的所有組合出現完,第一步dfs結束,接下來就是把top–清空原位置,然後換另外乙個數。

這裡的dfs出口depth一開始我設定等於n,這樣會少算包含輸入陣列中最後乙個數的資料。因為當輸入陣列的最後乙個數填進去,此時depth為n-1,還沒輸出,必須等下一步dfs才輸出。所以一定要關注dfs出口和資料儲存的關係,否則很容易錯!

#include

using namespace std;

int st[

100]

;int top=0;

int n=

5,m=3;

int a=

;void

dfs(

int depth)

st[top++

]=a[depth]

;dfs

(depth+1)

; top--

;//抹掉之前狀態,從depth加1開始,這樣用到的數不會重複

dfs(depth+1)

;return;}

intmain()

又看了別人的部落格,發現可以在排列的基礎上小優化就是組合,讓每乙個新加入的數比陣列中前乙個數大,這樣可以保證遞增順序,就不會有形如123 213 321的情況了,這種方法更加簡單!

僅僅是加了乙個判定,要求加入的數大於陣列中的前乙個數,這樣可以保證遞增.

#include

using namespace std;

int a=

;int n=

5,m=3;

int ans[10]

;bool vis[

111]

;void

dfs(

int cnt)

for(

int i=

1;i<=n;i++)}

}int

main()

DFS排列組合

初學,加強一下理解 每次dfs都是從1到n中 選出乙個數放在排列中第x個位置 void dfs int x int main void for int i 1 i r i dfs 1 關於回溯 我們可以以乙個1到3的全排列為例,則全排列過程可以想象為你穿過三層牆,每層牆都有三個編號為1 2 3的門,...

dfs排列組合問題

這幾天回顧了一下dfs演算法。這個演算法我覺得挺重要的,思想很基礎,是以後學習很多演算法的基礎吧,簡而言之就是遞迴,才開始接觸肯定會覺得,哇,很神奇,不知道怎麼做到的,其實只需要多加練習就可以了,當初我開始刷題的時候也是懵了很久。深度優先首先接觸來自於學資料結構的圖。深度優先是一種遍歷搜尋的方法。它...

DFS實現排列組合

所謂排列,是指從給定的元素序列中依次取出元素,需要考慮取出順序。比如,取出元素3,5,因取出順序的不同,則形成的序列與是不同的排列序列。對於長度為n的元素序列取出k個元素,則共有a n,k 種取法。所謂組合,也是從元素序列中依次取出元素,與排列不同的是不需要考慮取出順序 因此其取法數為c n,k l...