今天做oj题,有一道是求字典序法的前一个排列和下一个排列
在网络上查了很久,也没找到怎么求前一个排列。。。。
排列
对于给定的序列 A={a0,a1,...,an−1},按字典顺序打印前一个排列和下一个排列。
输入
以下格式给出了一个序列。
n
a0a1...an−1
输出
分别在第一行、第二行和第三行打印前一个排列、给定的序列和下一个排列。用空格字符分隔相邻元素。请注意,如果没有排列,则在相应行中不打印任何内容。
约束
- 1≤n≤9
- ai 由 1,2,...,n组成
示例输入 1
3
2 1 3
示例输出 1
1 3 2
2 1 3
2 3 1
示例输入 2
3
3 2 1
示例输出 2
3 1 2
3 2 1
唉 算了 自己动手丰衣足食!
众所周知
字典排序算法四步法:
字典排序:
第一步:从右至左找第一个左邻小于右邻的数,记下位置i,值list[a]
第二部:从右边往左找第一个右边大于list[a]的第一个值,记下位置j,值list[b]
第三步:交换list[a]和list[b]的值
第四步:将i以后的元素重新按从小到大的顺序排列
举例:125643的下一个字典序列
第一步:右边值大于左边的3<4,4<6,6>5,则i=2,list[a]=5
第二步:从右往左找出第一个右边大于list[a]=5的值,找到6>5,j=3;list[b]=6;
第三步:交换list[a]和list[b]的值,序列125643->126543
第四步:将位置2以后的元素重新排序,126543->126345;
结束: 126345即125643的下一个序列
那我把他反过来,不就是前一排序了吗!
字典上一个排序:
第一步:从右至左找第一个左邻大于右邻的数,记下位置i,值list[a]
第二部:从右边往左找第一个右边小于list[a]的第一个值,记下位置j,值list[b]
第三步:交换list[a]和list[b]的值
第四步:将i以后的元素重新按从大到小的顺序排列
最后一提交,哦,完美!
#include<iostream>
#include<algorithm>
using namespace std;
//求下一排序
int dir(int arr[], int n)
{
int num1 = -1,num2=0;
//1、从原排列中,从右至左,找到第一个左邻小于右邻的字符,记左邻位置为 a。
for (int i = n - 1; i >= 0; i--)
{
if (arr[i - 1] < arr[i])
{
num1 = i - 1;
break;
}
}
//2、重新从右至左,找到第一个比 list[a] 大的字符,记为位置为 b。
for (int i = n - 1; i >= 0; i--)
{
if (arr[i] >arr[num1])
{
num2 = i;
break;
}
}
if (num1 == -1)
return 0;
//3、交换 a 和 b 两个位置的值。
int temp = arr[num1];
arr[num1] = arr[num2];
arr[num2] = temp;
//4、将 a 后面的数,由小到大排列。
sort(arr + num1+1, arr + n);
}
//求上一排序
int dir_1(int arr[], int n)
{
int num1 = -1, num2 = 0;
//1、从原排列中,从右至左,找到第一个左邻大 于右邻的字符,记左邻位置为 a。
for (int i = n - 1; i >= 0; i--)
{
if (arr[i - 1] > arr[i])
{
num1 = i - 1;
break;
}
}
//2、重新从右至左,找到第一个比 list[a] 小的字符,记为位置为 b。
for (int i = n - 1; i >= 0; i--)
{
if (arr[i] < arr[num1])
{
num2 = i;
break;
}
}
if (num1 == -1)
return 0;
//3、交换 a 和 b 两个位置的值。
int temp = arr[num1];
arr[num1] = arr[num2];
arr[num2] = temp;
//4、将 a 后面的数,由da到xiao排列。
sort(arr + num1 + 1, arr + n,greater<int>());
}
int main()
{
int n;
cin >> n;
int arr1[10],bk1[10],bk2[10];
for (int i = 0; i < n; i++)
{
cin >> arr1[i];
bk1[i] = arr1[i];
bk2[i] = arr1[i];
}
int m = n;
int count = 1;
while (m>0)
{
count = count * m;
m--;
}
dir_1(bk1, n);
for (int i = 0; i < n; i++)
{
cout << bk1[i] << " ";
}
cout << endl;
for (int i = 0; i < n; i++)
{
cout << bk2[i] << " ";
}
cout << endl;
int num=dir(arr1, n);
if (num != 0)
{
for (int i = 0; i < n; i++)
{
cout << arr1[i] << " ";
}
cout << endl;
}
}