ACM算法训练之——下一个排列

时间:2021-04-10 09:50:15

ACM算法训练之——下一个排列

  • 内容描述:
    下一个全排列。
    例如n=5时,全排列3 2 4 5 1的下一个排列3 2 5 1 4。
    输入:整数n和一个{1,2,…,n}的全排列,用空格隔开。
    输出:字典顺序下的下一个排列,用空格隔开(没有下一个排列时不输出)。

  • 解题思路:
    按字典序排序,就要保证越小的数要越在前面即可。从后往前遍历数组,找到第一次出现前一个小于后一个数的数组序号(a[i] < a[i + 1]);再次遍历,从后往前找,找到第一个出现大于a[i]位置的数a[j],交换a[i]和a[j],然后把i后面的几个数按字典序排列好即可。

  • 示例代码:
#include <stdio.h>

void swap(int *a,int *b)
{
int t;
t = *a;
*a = *b;
*b = t;
}
void sort(int a[],int i,int n)
{
int j;
for(; i <= n-1;i++)
for(j = i+1;j <= n;j++)
{
if(a[i] > a[j])
swap(&a[i],&a[j]);
}
}
int judge(int a[],int n)
{
int i,j;
i = n - 1;
while( i > 0 && a[i] > a[i+1])
i--;
if(i==0) //不存在下一个排列
return 0;

j = n;
while(j > 0 && a[i] > a[j])
j--;

swap(&a[i],&a[j]); //交换
sort(a,i+1,n); //后面部分排序

return 1;
}

int main()
{
int a[150],n,i;
scanf("%d",&n);
for(i = 1; i <= n; i++)
scanf("%d",&a[i]);
if(judge(a,n))
{
for(i = 1; i <= n; i++)
printf("%d ",a[i]);
}
else
{
printf("this is the last array!"); //没有下一个排列了
}
printf("\n");

return 0;
}