Leetcode c语言-Next Permutation

来源:互联网 发布:如何让win7网络更流畅 编辑:程序博客网 时间:2024/05/22 10:47

Title:

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

The replacement must be in-place, do not allocate extra memory.

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1


这道题就是求全排列的问题,给定一个数组,求出其下一个比它大的数组。

对于一个任意序列,最小的序列是增序,最大的序列为减序。也就是说比如1234位最小,4321为最大。1234的下一个比它大的数组是1243,再下一个是1324,再下一个是1342......。依次下去。4321的下一个就是1234。


那么解题思路是什么?

比如1243,它的下一个应该是1324. 观察1243,它的子序列43已经是减序列,也就是43已经是最大的子序列了,不可能通过交换里面的元素得到更大的序列。因此要移动到第二位2,对第二位进行替换,要在子序列43中找到一个比2更大的元素替换2的位置,也就是变成1342,此时该序列比1243要大,但并不是最终结果,因为1342与1243中间还有1324,它比1342更接近1243,且大于1243. 那么要对1342再进行排序,此时,前面两位13不用移动,只需对子序列42进行变换成24就行。这里的技巧是将子序列从小到大排序即可。因为13已经保证了比1243要大,所以42排列成最小的24即可。



那么如何找到这个减序列呢?很多人都会从头也就是1开始找,判断到次元素和下一个元素的大小,如果下一个元素更小,说明是减序列。但此方法存在漏洞,如果一个序列存在多个减序列,比如2143,那么会判断到第一个减序列21,这样显然不对。

正确方法是从后往前找,找到第一个子减序列,即可保证这个减序列就是我们需要的。因为是从小往大找,不是减序列的那个边界元素2就是我们需要替换的。



还有一些特殊情况,比如4321,这种已经是最大的了,那么它的下一个是1234,不能通过上面的常规思路去解答。只需要判断如果这个序列的数字是从大排到小的,那么就可断定该序列最大,它的下一个是它的倒序,用个倒序算法即可。


Solution:

void sort(int* nums, int numsSize, int index) {int i;    int j;    int tmp;    int flag=0;    for (i=index;i<numsSize;i++) {    for (j=index;j<numsSize-1;j++) {    if (nums[j]>nums[j+1]) {    tmp=nums[j];    nums[j]=nums[j+1];    nums[j+1]=tmp;                flag=1;    }    }        if (flag==0)            break;    }}void nextPermutation(int* nums, int numsSize) {    int i=numsSize-1;    int j=numsSize-1;    int tmp;    int m;    while (i>=1) {    if (nums[i]>nums[i-1]) {    while (nums[i-1]>=nums[j]) {    j--;    }    tmp=nums[i-1];    nums[i-1]=nums[j];    nums[j]=tmp;    sort(nums,numsSize,i);    return;    }    else if(i==1) {    for (i=0;i<numsSize/2;i++) {    tmp=nums[i];    nums[i]=nums[numsSize-1-i];    nums[numsSize-1-i]=tmp;    }    return;    }    else    i--;    }}



其中的排序算法是冒泡排序。

原创粉丝点击