Solution 1(時間複雜度約爲O(n^2),空間複雜度爲O(n))
#include <iostream>
#include<cstdlib>
#include<vector>
#define N 54
using namespace std;
void func(vector<int>&num){
int hash[N+1]={0};
int cnt=0,i=0;
while(cnt<N){
int val=rand()%N+1;
if(!hash[val]){
num[i++]=val;
hash[val]=1;
++cnt;
}
}
return ;
}
int main()
{
vector<int>data(N);
func(data);
for(int i=0;i<N;++i)
cout<<data[i]<<" ";
cout<<endl;
return 0;
}
Solution 2(時間複雜度約爲O(n),空間複雜度爲O(1))
Knuth-Durstenfeld Shuffle算法
Knuth 和 Durstenfeld 在Fisher 等人的基礎上對算法進行了改進,在原始數組上對數字進行交互,省去了額外O(n)的空間。該算法的基本思想和 Fisher 類似,每次從未處理的數據中隨機取出一個數字,然後把該數字放在數組的尾部,即數組尾部存放的是已經處理過的數字。
算法步驟爲:
1. 建立一個數組大小爲 n 的數組 arr,分別存放 1 到 n 的數值;
2. 生成一個從 0 到 n - 1 的隨機數 x;
3. 輸出 arr 下標爲 x 的數值,即爲第一個隨機數;
4. 將 arr 的尾元素和下標爲 x 的元素互換;
5. 同2,生成一個從 0 到 n - 2 的隨機數 x;
6. 輸出 arr 下標爲 x 的數值,爲第二個隨機數;
7. 將 arr 的倒數第二個元素和下標爲 x 的元素互換;
……
如上,直到輸出n個數爲止
時間複雜度爲O(n),空間複雜度爲O(1),缺點必須知道數組長度n。
#include <iostream>
#include<cstdlib>
#include<vector>
#define N 54
using namespace std;
void xipai(vector<int>&data){
int cnt;
for(int i=0;i<N;++i){
cnt=rand()%(N-i);
swap(data[cnt],data[N-i-1]);
}
return ;
}
int main()
{
vector<int>data(N);
for(int i=0;i<N;++i)
data[i]=i+1;
xipai(data);
for(int i=0;i<N;++i)
cout<<data[i]<<" ";
return 0;
}