解题思路及代码:
/*
算法概述:这个题实际上是要找下一个更大的数
要想得到下一个更大的数,就需要将后面的数与前面的数进行交换;
而且,要想让下一个数增大的幅度最小,就需要尽可能的在右端发生交换,所以需要从后往前查找。
那么问题来了,如何找到需要交换的两个数呢?
原则是后面的大数和前面的小数进行交换,那么可以先从后往前越过序列中的降序序列(如果有的话),
找到第一个相邻的升序数对(i,j),i<j,为什么是找相邻的呢,因为判断后面的降序序列用的就是相邻
两个数的大小关系,当发现不是降序的时候自然也是从相邻的数发现的。
然后从最后一个数往j开始找,找第一个比i大的数(保证交换的大数是最小的大数)与i交换,
交换之后j之后的数必然也是降序,这时不要忘了我们的目的是让下一个数增大的幅度最小,现在
把后面的大数换到前面了,那么要想使幅度最小,必须让j后面的数升序排列。
害,写的貌似有点乱,这个逻辑我理解了好久……
*/
void sort(int* nums, int s, int e) {
int i = 0, j = 0;
int temp = 0;
for (i = e; i > s; i--) {
for (j = s; j < i; j++) {
if (nums[j] > nums[j + 1]) {
temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
}
}
void nextPermutation(int* nums, int numsSize){
int temp = 0;
int i = 0, j = 0;
for (i = numsSize - 1; i > 0; i--) {
if (nums[i] > nums[i - 1]) {// 相邻的一个升序序列
break;
}
}
if (i == 0) {// 原序列为一个降序序列,则逆序输出
for (i = numsSize - 1; i >= 0; i--)
printf("%d ", nums[i]);
printf("\n");
return ;
}
for (j = numsSize - 1; j >= i; j--) {// 找最小的大数与前面的小数交换
if (nums[j] > nums[i - 1]) {
temp = nums[j];
nums[j] = nums[i - 1];
nums[i - 1] = temp;
break;
}
}
sort(nums, i, numsSize - 1);// 将后面的数排为升序,使得下一个更大的数最小
for (i = 0; i < numsSize; i++)
printf("%d ", nums[i]);
printf("\n");
}
我无语了……
害,原来这个题是不要输出的,只要数组里面的值变了就行
通过的代码:
/*
算法概述:这个题实际上是要找下一个更大的数
要想得到下一个更大的数,就需要将后面的数与前面的数进行交换;
而且,要想让下一个数增大的幅度最小,就需要尽可能的在右端发生交换,所以需要从后往前查找。
那么问题来了,如何找到需要交换的两个数呢?
原则是后面的大数和前面的小数进行交换,那么可以先从后往前越过序列中的降序序列(如果有的话),
找到第一个相邻的升序数对(i,j),i<j,为什么是找相邻的呢,因为判断后面的降序序列用的就是相邻
两个数的大小关系,当发现不是降序的时候自然也是从相邻的数发现的。
然后从最后一个数往j开始找,找第一个比i大的数(保证交换的大数是最小的大数)与i交换,
交换之后j之后的数必然也是降序,这时不要忘了我们的目的是让下一个数增大的幅度最小,现在
把后面的大数换到前面了,那么要想使幅度最小,必须让j后面的数升序排列。
害,写的貌似有点乱,这个逻辑我理解了好久……
*/
void reverse(int* nums, int s, int e) {
int i = 0;
int temp = 0;
for (i = s; i <= (s + e) / 2; i++) {
temp = nums[i];
nums[i] = nums[s + e - i];
nums[s + e - i] = temp;
}
}
void nextPermutation(int* nums, int numsSize){
int temp = 0;
int i = 0, j = 0;
for (i = numsSize - 1; i > 0; i--) {
if (nums[i] > nums[i - 1]) {// 相邻的一个升序序列
break;
}
}
if (i == 0) {// 原序列为一个降序序列,则逆序排列
reverse(nums, 0, numsSize - 1);
return ;
}
for (j = numsSize - 1; j >= i; j--) {// 找最小的大数与前面的小数交换
if (nums[j] > nums[i - 1]) {
temp = nums[j];
nums[j] = nums[i - 1];
nums[i - 1] = temp;
break;
}
}
reverse(nums, i, numsSize - 1);// 逆序,使得下一个更大的数最小
for (i = 0; i < numsSize; i++)
printf("%d ", nums[i]);
printf("\n");
}