下一个排列-力扣31-java

该问题要求在给定的整数数组中找到下一个字典序更大的排列。如果不存在更大的排列,则需将数组重排为最小排列。算法首先从后向前找到第一个减小的数字,然后找到比这个数字大的最小数字进行交换,并将交换后数字的右侧部分逆序,以得到下一个排列。当没有减小的数字时,说明数组已经是最大排列,直接逆序即可。
摘要由CSDN通过智能技术生成

一、题目描述

整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。

例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。

整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。

例如,arr = [1,2,3] 的下一个排列是 [1,3,2] 。

类似地,arr = [2,3,1] 的下一个排列是 [3,1,2] 。

而 arr = [3,2,1] 的下一个排列是 [1,2,3] ,因为 [3,2,1] 不存在一个字典序更大的排列。

给你一个整数数组 nums ,找出 nums 的下一个排列。

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

示例 1:

输入:nums = [1,2,3]

输出:[1,3,2]

示例 2:

输入:nums = [3,2,1]

输出:[1,2,3]

示例 3:

输入:nums = [1,1,5]

输出:[1,5,1]

来源:力扣(LeetCode)

链接:https://leetcode.cn/problems/next-permutation

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、运行结果

三、解题思路

首先从后往前找到第一个减小的数字,记录其下标为index,如1357642,找到的数字是5,重点:该数字后面的所有数字是按从大到小排列的。如果不是,则表示在该数字之后还出现过减小的数字,那么当前数字就是不是倒序第一个减小的,矛盾。

如果没有找到减小的数字,就表示每一位数字都是按降序排列的,没有下一个更大的序列,逆置该数组返回即可。

如果找到了index,则从该下标往后找到比nums[index]大,而且是这数中最小的,如上面的数字找到的是6,然后交换5和6的位置,则数组变为1367542,index后面的数字仍是降序排列(7542),将index后面的所有数字变为升序排列(最小的排列)即可,此时数字变为1362457,即是下一个更大的排列。

四、AC代码

class Solution {
    public void nextPermutation(int[] nums) {
        int len = nums.length;
        int index = -1;
        for(int i=len-2; i>=0; i--){  //从后往前找到第一个下降的数字下标
            if(nums[i] < nums[i+1]){
                index = i;
                break;
            }
        }
        if(index == -1){  //不存在下一个更大的排列
            int i=0, j = len-1;
            while(i < j) {  //重新排列成最小的排列
                swap(nums, i, j);
                i++; j--; 
            }
            return ;
        }
        int i = index;
        //寻找后面比该数字大的最小数字下标
        while(i < len-1 && nums[i+1] > nums[index]) i++;  
        swap(nums, i, index);  //交换两个位置的元素
        int j=index+1, k = len-1;
        while(j < k){  //将该数字后面的数排成最小序列(逆置)
            swap(nums, j, k);
            j++; k--;
        }
    }
    private void swap(int[] nums, int i, int j){
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值