实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
这个题题目描述的并不清楚,看完题目真的没搞明白在干什么。在看了评论区之后,我大概总结了下,举个例子,给定一个排序为123,它的下一个排序有132,213,231,312,321这几个,但是题目要求的是下一个更大的排序,即132为所要返回的值,所以只要找出这个排序打乱之后大于本身的最小排序。
题解:
void reverse(int *nums, int numsSize) {
int i = 0;
int j = numsSize - 1;
while (i < j) {
swap(&nums[i], &nums[j]);
i++;
j--;
}
return;
}
void swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
return;
}
int cmp(const void *a, const void *b) {
return *(int*)a - *(int*)b;
}
void nextPermutation(int* nums, int numsSize){
if (numsSize <= 1) {
return;
}
int i, j;
for (i = numsSize - 2; i >= 0; i--) {
if (nums[i] < nums[i + 1]) { /* 找到前面数小于后面数的下标 */
for (j = numsSize - 1; j >= i + 1; j--) {
if (nums[j] > nums[i]) { /* 从后往前找到nums[j]>nums[i] */
swap(&nums[i], &nums[j]); /* 交换后进行排序 */
qsort(nums + i + 1, numsSize - i - 1, sizeof(nums[0]), cmp);
return;
}
}
}
}
/* 如果不存在更大排列, 则反序 */
reverse(nums, numsSize);
return;
}
补充:qsort函数,这个是C语言内置的快速排序,它的时间复杂度为n*log(n),头文件为stdlib.h,如何排序是根据cmp函数的返回值来决定。
a.返回值小于0,p1所指向的元素会被排在p2所指向的元素前面。
b.返回值等于0,p1所指向的元素与p2所指向的元素的顺序不确定。
c.返回值大于0,p1所指向的元素会被排在p2所指向的元素后面。