真的猛士,敢于直面惨淡的人生,敢于正视淋漓的鲜血。这是怎样的哀痛者和幸福者?然而造化又常常为庸人设计,以时间的流驶,来洗涤旧迹,仅使留下淡红的血色和微漠的悲哀。在这淡红的血色和微漠的悲哀中,又给人暂得偷生,维持着这似人非人的世界。我不知道这样的世界何时是一个尽头!
我们还在这样的世上活着;我也早觉得有写一点东西的必要了。离数期末也已不足两个月,数据结构可能真的要凉了罢,我正有写一点东西的必要了。本来想在自己公众号上更的,结果被其他人说不可能有人看,还会有人取关。emmmm那我就只能在这更了。如果有时间就每日一题,没时间就每周一题。
下一排列
将给定数字序列重新排列成字典序中下一个更大的排列。如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
样例:
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
输入
第一行是数字n(n <= 100)
接下来是n个数字。
输出
输入的n个数字的下一排列。每个数字之间用空格隔开。
样例输入
5
1 2 3 4 5
样例输出
1 2 3 5 4
思路:寻找下一排列就是找比这个数大的下一个整数。所以我们要调整这个数里面每个数的位置,而且幅度要尽可能小。我们可以从后往前找到第一个不是升序的数,即这个数比后面的数小,例如1234765321,从最后一位到7都是升序排列,而4比7小。然后我们从4开始往后找,找到比4大且相差最小的数,即5,两者调换位置,这样就得到了比原数在百万位大的下一个数,然后把后面的数从小到大排列就找到了比原数大的下一个数。
下面贴一张leetcode上官方解答动图,有助于理解:
代码:
#include<iostream>
using namespace std;
int findnearest(int*arr, int size, int num)
{
int min_index = 0;
for (int i = 0; i < size; i++)
{
if ((arr[i] - num < arr[min_index] - num)&& (arr[i] - num>0))
min_index = i;
}
return min_index;
}
void swap(int*a, int*b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void sort(int *arr, int size)
{
int temp = 0;
for (int i = 0; i < size-1; i++)
{
for (int j = 0; j < size - 1 - i; j++)
if (arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
int main()
{
int num;
cin >> num;
int *arr = new int[num];
for (int i = 0; i < num; i++)
{
cin >> arr[i];
}
int j = -1;
for (int i = num - 1; i >= 1; i--)
{
if (arr[i - 1] < arr[i])
{
j = i - 1;
break;
}
}
if (j != -1)
{
int index = j + 1 + findnearest((arr + j + 1), num - j - 1, arr[j]);
swap(arr[j], arr[index]);
sort((arr + j + 1), num - j - 1);
}
else
{
sort(arr, num);
}
for (int i = 0; i < num; i++)
{
cout << arr[i] << " ";
}
return 0;
}
扫描二维码关注公众号,回复:
4341515 查看本文章