2.1.12 Next Permutation

Link: https://oj.leetcode.com/problems/next-permutation/

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

我的思路:2nd time: 我知道第一步要从后往前找一个最长升序序列。在升序序列结束的下一个位置p,就是要替换的数。

e.g. 5, 3, 7, 4, 2, 1

7<-4<-2<-1是一个升序,所以换掉3。但下一步就不知道怎么做了。

我的初始代码:

public class Solution {
    public void nextPermutation(int[] num) {
        for(int i = num.length-2; i >=0; i--){
            if(num[i] < num[i+1]){
                int tmp = num[i];
                for(int j = i+1; j < num.length; j++){
                    if(num[j] > tmp){
                        
                    }
                }
                num[i-1] = num[i];
                num[i] = tmp;
                return;
            }
            //else continue;
        }
        
        //if the entire array is decreasing
        int l = 0;
        int h = num.length - 1;
        int tmp = 0;
        while(l < h){
            tmp = num[l];
            num[l] = num[r];
            num[r] = tmp;
            l++;
            r--;
        }
    }
}


Approach I: 正确答案:http://blog.csdn.net/linhuanmars/article/details/20434115

比如排列是(2,3,6,5,4,1): (2) 如果p存在,从p开始往后找,找到下一个比A[p]大的数字 (我的理解:实际上是找到第一个比A[p]小的数字,然后看它的前一个,也就是第一个比num[p]大的数),然后两个调换位置,比如例子中的4。调换位置后得到(2,4,6,5,3,1)。最后把p之后的所有数字倒序,比如例子中得到(2,4,1,3,5,6), 这个即是要求的下一个排列。

这是因为4是下一个比A[p]大的数,所以调换后,p之后的所有数一定是降序排列(6, 5, 3, 1),所以反过来即可。


Approach II: 找到p以后,数组从最后往前找,找到的第一个比num[p]大的数,就是对的。因为num[p]以后的数递减。

在初始代码上改动的代码:

public class Solution {
    public void nextPermutation(int[] num) {
        for(int i = num.length-2; i >=0; i--){
            if(num[i] < num[i+1]){
                int j = 0;
                for(j = num.length-1; j >i; j--){
                    if(num[j] > num[i]){
                        break;
                    }
                }
                int temp = num[j];
                num[j] = num[i];
                num[i] = temp;
                Arrays.sort(num, i+1, num.length);
                return;
            }
        }
        //else continue;
        //if the entire array is decreasing
        int l = 0;
        int h = num.length - 1;
        int tmp = 0;
        while(l < h){
            tmp = num[l];
            num[l] = num[h];
            num[h] = tmp;
            l++;
            h--;
        }
        return;
    }
        
}
http://blog.csdn.net/linhuanmars/article/details/20434115"最坏情况需要扫描数组三次,所以时间复杂度是O(3*n)=O(n)" //why 最坏扫三次?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值