歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> Linux教程

百度面試題——需找下一個排列(Find next permuation, POJ 1883)

面試中關於排列的題目還是蠻常見的,之前有個同學面百度,就遇到了一個排列題目,分享一下。

題目描述:
給你一個數組,如果是按照數字的大小排序,那麼請你輸出當前數組的下一個排列是什麼

例如, 下面的數據,就是按照排列序生成的四組數據。

3 1 2 4 5
3 1 2 5 4
3 1 4 2 5
3 1 4 5 2

雖然有個函數叫next_permutation, 不過做OJ還好,面試這個一定不行啦,所以還是自己分析一下。

分析:
我們用字典序的排列生成方法:


生成給定全排列的下一個排列

所謂一個的下一個就是這一個與

下一個之間沒有其他的。這就要求這一個與下一個有盡可能長的共同前綴,也即變化限制在盡可能短的後綴上。

 算法分三個步驟:

一般而言,設P是[1,n]的一個全排列。

1.  P=P1P2…Pn=P1P2…Pj-1PjPj+1…Pk-1PkPk+1…Pn

j=max{i|Pi<Pi+1},k=max{i|Pi>Pj}

2.  對換Pj,Pk,將Pj+1…Pk-1PjPk+1…Pn翻轉,

3. P’= P1P2…Pj-1PkPn…Pk+1PjPk-1…Pj+1即P的下一個。

代碼如下:

  1. Memory: 168K        Time: 469MS 
  2. Language: C++       Result: Accepted 
  3. Source Code 
  4. #include<stdio.h>  
  5. #include <memory.h>  
  6.  
  7. void swap( int &a, int &b) 
  8.     a = a ^ b; 
  9.     b = a ^ b; 
  10.     a = a ^ b; 
  11.  
  12.  
  13. bool GetNextPermutation(int a[], int size) 
  14.     int m = size - 1; 
  15.     int i,j; 
  16.     while(m > 0 && a[m-1] > a[m]) // step 1  
  17.     { 
  18.         m--; 
  19.     } 
  20.  
  21.     //in this case, the current permutation is the last  
  22.     if(m == 0) //  
  23.     { 
  24.         for( i = 0, j = size - 1; i < j; i++, j--) 
  25.         { 
  26.             swap(a[i], a[j]); 
  27.         } 
  28.         return false
  29.     } 
  30.  
  31.     for( j = size - 1; j > m - 1; j--)//step 2  
  32.     { 
  33.         if(a[j] > a[m-1]) 
  34.         { 
  35.             swap(a[j], a[m-1]); 
  36.             break
  37.         } 
  38.     } 
  39.  
  40.     for( i = m, j = size - 1; i < j; i++, j--)//step 3  
  41.     { 
  42.         swap(a[j], a[i]); 
  43.     } 
  44.     return true
  45.  
  46. void printArray(int a[], int size) 
  47.     int i; 
  48.  
  49.     for( i = 0; i < size; i++) 
  50.     {   
  51.         if( i == 0) 
  52.         { 
  53.             printf("%d", a[i]); 
  54.         } 
  55.         else 
  56.         { 
  57.             printf(" %d", a[i]); 
  58.  
  59.         } 
  60.     } 
  61.     printf("\n"); 
  62. int main() 
  63.     int nSize; 
  64.     int a[1024]; 
  65.     int ncase; 
  66.  
  67.     scanf("%d", &ncase); 
  68.     int n,k; 
  69.     while(ncase--) 
  70.     { 
  71.         scanf("%d%d", &n, &k); 
  72.  
  73.         forint i = 0; i < n; i++) 
  74.         { 
  75.             scanf("%d", &a[i]); 
  76.         } 
  77.  
  78.         while(k--) 
  79.         { 
  80.             GetNextPermutation(a, n); 
  81.              
  82.         } 
  83.         printArray(a, n); 
  84.      
  85.     } 
  86.     return 0; 
Copyright © Linux教程網 All Rights Reserved