直接選擇序列的方法解本題,但是最壞時間效率是O(n*n),故此不能達到0MS。ios
使用刪除優化,那麼就可以達到0MS了。算法
刪除優化就是當需要刪除數組中的元素爲第一個元素的時候,那麼就直接移動數組的頭指針就可以了,那麼時間效率就是O(1)了,而普通的刪除那麼時間效率是O(n),故此大大優化了程序。數組
怎樣直接選擇第k個序列,可以參考本博客的Leetcode題解。Leetcode題有個如出一轍的題目。只是沒有使用刪除優化。函數
看見本題的討論中基本上都是使用STL解,還有沾沾自喜的傢伙,只是使用STL解決本題儘管是可以,但是那是因爲本題的數據很是弱;大數據
因爲使用STL的時間效率是O(n*m),當中n多是1000, 而m多是10000,故此會達到1千萬的數據處理,隨便添加個大數據用例就會超時。優化
故此使用STL來解決本題事實上是很是次,很是0基礎的解法了。spa
#include <stdio.h> #include <vector> #include <string.h> #include <algorithm> #include <iostream> #include <string> #include <limits.h> #include <stack> #include <queue> #include <set> #include <map> using namespace std; const int MAX_N = 1001; int arr[MAX_N], N, M, tbl[MAX_N]; void genSeqNum() { int mth = M-1; memset(tbl, 0, sizeof(int) * N); tbl[N-1] = 0; for (int i = N-2, d = 2; i >= 0 && mth > 0; i--, d++) { tbl[i] = mth % d; mth /= d; } } void eraseNth(int A[], int i) { --N; for (; i < N; i++) { A[i] = A[i+1]; } } void printNums() { genSeqNum(); int *A = arr; printf("%d", A[tbl[0]]); if (!tbl[0]) A++, N--; else eraseNth(A, tbl[0]); int t = 1;//定位tbl下標 while (N > 0)//優化以後的算法 { for (; N && !tbl[t]; t++)//主要優化地方 { printf(" %d", *A);//輸出爲零的,不用使用刪除函數 A++, N--;//又一次定位數列 } if (!N) break;//已經輸出完成 printf(" %d", A[tbl[t]]);//不爲零的選擇,使用刪除函數 eraseNth(A, tbl[t]); t++; } putchar('\n'); } int main() { while (scanf("%d %d", &N, &M) != EOF) { for (int i = 0; i < N; i++) { arr[i] = i+1; } printNums(); } return 0; }