[leetcode-31]Next Permutation(C)

本文详细解释了如何通过迭代方法在不使用额外内存的情况下,将一组数字排列转换为字典序中紧随其后的排列。

问题描述:
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

分析:这道题有必要说说题意。假设有5个数:1,2,3,4,5,那么会有一个全排列。12345,12354,12435,12453,,,,,,共5!种从小到大的排列。那么12345的下一个数就是12354。依次类推,我们知道最后一个数:54321,那它的下一个数就是12345了。
题意明白了,算法也是有现成的。

  1. 从右向左查找出现满足条件的第一个元素j。该元素大于右边的元素
  2. 如果找不到,直接反转整个数组
  3. 然后在j的右边,找到大于nums[j]的最小元素i,且尽量向右延伸
  4. 交换nums[i]和nums[j]
  5. 对j右边的元素进行反转。

代码如下:4ms

void reverse(int *nums,int start,int end){
    int left = start;
    int right = end-1;

    int tmp;
    while(left<right){
        tmp = nums[left];
        nums[left] = nums[right];
        nums[right] = tmp;
        left++;
        right--;
    }
}
void nextPermutation(int* nums, int numsSize) {
    if(numsSize<2)
        return;
    int i,j;
    for(i = numsSize-2;i>=0;i--){
        if(nums[i]<nums[i+1])
            break;
    }
    if(i<0){
        reverse(nums,0,numsSize);
        return;
    }
    int min = nums[i+1];
    int index = i+1;
    for(j = i+2;j<numsSize;j++){
        if(nums[j]>nums[i]&&nums[j]<=min){
            min = nums[j];
            index = j;
        }
    }

    nums[index] = nums[i];
    nums[i] = min;

    reverse(nums,i+1,numsSize);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值