下一个排列

69 篇文章 1 订阅
63 篇文章 0 订阅

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

方法:扫描法
思路:
1,首先要找到满足条件的数组索引,例如:1,4,5,7,6,3
2,从数组的最后一个元素开始找,直到找到索引i,i处的元素比i + 1 处的元素小 ,那么就找到了!就是5这个元素位置,也就是 i = 2;
3,然后拿着这个位置的元素,从数组的最后一个位置开始找比他小的元素,就是3所在的位置5;
4,然后换位数组变成1,4,3,7,6,5 ,并且需要对数组i位置右边的元素进行升序排列,也就是i=3,也就是7这个元素除;
5,重新排序在此题中很简单,因为右边的元素是从i+1到length-1是降序,我们需要从i+1处开始到length-1是升序,所以只需要将元素头尾对应元素互换位置即可;

class Solution {
    public void nextPermutation(int[] nums) {
        int end = nums.length - 2;
        //有则换位,有半段重拍,无则升序全部重拍
        while (end >= 0 && nums[end + 1] <= nums[end])
            end --;//记录刚好满足条件的索引位置
        if (end >= 0) {
            int temp = nums.length - 1;
            while (temp >= 0 && nums[temp] <= nums[end] )
                temp --; //找到换位点
            swap(nums, end, temp);
        }
        //换位后对end位之后的数组进行重排序(没有换位则刚好全部升序排列)
        reverse(nums, end + 1);
    }
    
    //重排序
    private void reverse(int[] nums, int start) {
        int end = nums.length - 1;
        while (start < end) {//两两换位,头尾
            swap(nums, start, end);
            start ++;
            end --;
        }
    }
    //换位
    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

注意:对符合目标元素索引的记录,以免出错;以及对while循环的使用。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值