百度面试题——需找下一个排列(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; 
  • 1
  • 2
  • 下一页

相关内容