前段時間面試了一家公司的圖像崗位,居然盡問我C++的知識,還讓我寫全排列,表示無語……,不過還是硬着頭皮寫了下,這麼久沒接觸算法,之前也沒寫過全排列,汗顏呀,回來還發現寫法有些low,貼出當時的代碼,mark下學業不精的尷尬,順便熟悉一下MarkDown,以後再也不用Word寫博客了,
題目
輸出 1,2,…,N的全排列
樣例
基本思路是DFS,考慮到遞歸的棧消耗,於是用數組來實現非遞歸,時間複雜度爲
- flag: 是否已經選中的標記,已經選擇了爲1,否則爲0
- state: 記錄上一次搜索到的數字
- data: 存放全排列
#include"iostream"
#include <iomanip>
using namespace std;
void fullPerm(int N)
{
int *flag=new int [N];
int *state=new int[N];
int *data = new int[N];
memset(flag,0,sizeof(int)*N);
memset(state, 0, sizeof(int)*N);
int d = 0;
int cnt = 1;
while (true)
{
if (N == d)//到底了
{
cout <<setw(3)<<cnt++<<": ";
for (int i = 0; i < N; i++)
cout << data[i]+1 << " ";
cout << endl;
d--;//回溯
flag[state[d]] = 0;//上去的時候釋放選中的元素
state[d]++;
}
else
{
int s = state[d];
for (; s < N; s++)//尋找下一個沒有被選中的元素
{
if (0 == flag[s])//往下搜索
{
data[d] = s;
flag[s] = 1;//下來的時候選擇元素
state[d] = s;
d++;
break;
}
}
if (s == N)//中間層回溯
{
state[d] = 0;
d--;
if (d < 0)//回溯到了最頂層
break;
flag[state[d]] = 0;
state[d]++;
}
}
}
delete[] flag;
delete[] state;
delete[] data;
}
void main(void)
{
int n;
cin >> n;
fullPerm(n);
system("pause");
}