1. 程式人生 > 其它 >[dfs入門]全排列問題

[dfs入門]全排列問題

first:題目

描述

輸出自然數\(1\)\(n\)所有不重複的排列,即\(n\)的全排列,要求所產生的任一數字序列中不允許出現重複的數字。

輸入

輸入一個數字\(n(1≤n≤9)\)

輸出

\(1\)~\(n\)組成的所有不重複的數字序列,每行一個序列。

second:分析

直接遞迴即可。

\(dep\)代表列舉的深度,即第\(dep\)個數應該放什麼,再一一列舉,如果這個數沒有用到,則使用,然後列舉下一層,結束後再列舉下一個數。

當全部列舉完後,即\(dep=n+1\)時,輸出,時間複雜度為\(O(n\ !)\)

third:新知

我們可以開一個\(bool\)陣列來判斷是否列舉,如果為\(false\)

則沒有,反之,\(true\)則有。

列舉時,我們先判斷有沒有用,如果沒有用過,就加入,並且這個數變成\(true\),遞迴下一層。

當這個數遞迴完以後,再把這個數變成\(true\),繼續列舉,這叫做回溯法。

fourth:注意

1、為了不重複,要設陣列表示狀態。

2、及時回溯,以便下次搜尋。

3、當搜到第\(n+1\)次時,代表全部搜好了,然後輸出。

fifth:程式碼

#include<bits/stdc++.h>
using namespace std;
int n;
int a[101];
bool node[101];
void write()
{
	for(int i=1;i<=n;i++)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;//輸出
}
void dfs(int dep)
{
	if(dep==n+1)//搜尋完了
	{
		write();
		return;
	}
	for(int i=1;i<=n;i++)
	{
		if(node[i]==false)//沒有用過
		{
			a[dep]=i;
			node[i]=true;//使用
			dfs(dep+1);//下一個數
			node[i]=false;//回溯
		}
	}
}
int main()
{
	cin>>n;
	dfs(1);//從第一層開始
	return 0;
}