DFS有重複數字的全排列

2021-08-11 07:39:27 字數 1350 閱讀 6072

此文寫於2017-11-25

全排列就不說了,乙個next_permutation就解決了。

但是有重複的數字還能用基本的全排列嗎?

答案顯然是不能的,我們需要一些語句來幫助我們避免重複。

讓我們結合**來分析

//有重複的全排列

#include

#include

using

namespace

std;

const

int mn=105;

int a[mn],n,x,ans[mn],l;

bool vis[mn];

void print()

void dfs(int k)

int last=-1;

for(int i=1;i<=n;i++)

if(vis[i]==false&&a[i]!=last)

vis[i]=true,ans[k]=a[i],last=a[i],dfs(k+1),vis[i]=false;

} int main()

我們主要來說說這個dfs函式

如果k>n,那麼就說明到了邊界,直接輸出;

關鍵是中間的判斷重複與查詢排列這一部分了

這段**採用的是判斷是否與上乙個數字重複–可能不太好理解,我舉個例吧:

例如輸入的是:1 2 2

那麼它的全排列就是:

①1 2 2

②2 1 2

③2 2 1

執行過程是這樣的

首先進去就是1 2 2

然後返回變成1 2

發現不能是1 2 2

然後返回成1

發現不能是1 2

然後返回,更新成2

然後更新成2 1 2

返回變成2 1

返回變成2

更新成2 2 1

完畢我們發現,我們可以直接利用數字出現的次數來做,方法如下,看**就會(計數法)(約定一下數字大小不超過30)

#include

#include

using

namespace

std;

int b[105];

int ans[105],n,a[105],cnt;

void dfs(int k)

for(int i=1;i<=30;i++)

if(b[i])

}int main()

sort(a+1,a+n+1);

dfs(1);

return

0;}

46 全排列(無重複數字)

這是無重複數字的全排列。注意遞迴函式中的迴圈 迴圈起始位置 和used陣列的使用 class solution void dfs int nums for int i 0 i還學習了交換法,不用申請used陣列。但是看了看,好像空間也沒節省多少啊。可能是因為為了轉換成list要將int轉換成inte...

全排列(無重複數)

題目鏈結 給定乙個 沒有重複 數字的序列,返回其所有可能的全排列。示例 輸入 1,2,3 輸出 1,2,3 1,3,2 2,1,3 2,3,1 3,1,2 3,2,1 1.返回值和引數 輸入排列陣列和記錄陣列中的元素是否被使用的陣列 2.單層遞迴邏輯 遍歷陣列每次取乙個元素新增到path,但是要取沒...

全排列(有重複數)

題目鏈結 給定乙個可包含重複數字的序列 nums 按任意順序 返回所有不重複的全排列。示例 1 輸入 nums 1,1,2 輸出 1,1,2 1,2,1 2,1,1 示例 2 輸入 nums 1,2,3 輸出 1,2,3 1,3,2 2,1,3 2,3,1 3,1,2 3,2,1 1 nums.le...