【Hot100】LeetCode—31. 下一个排列



思路

  • ① 从右边找出一个尽可能大的数,和左边的数进行交换 ——> 交换后得到的数 就是 字典序更高
  • ② 字典序高,但不代表其就是下一个 ——> 如何找下一个?
    • 左边的小数,尽可能靠右
    • 右边的大数,尽可能的小(比左边的小数大一点点)

目标

  • ① 找到数组的拐点 ——> 从右向左遍历 ——> nums[i] < nums[i+1] 则找到了拐点 i+1
  • ② 找到拐点右侧第一个 nums[i] 大的元素,此时记录 为 j ——> 从右向左遍历
  • ③ 将元素 i 和 元素 j 交换,之后 sort(i+1,len-1)
  • ④ 如果不存在拐点,此时直接 reverse 整个数组
    在这里插入图片描述

2- 实现

31. 下一个排列——题解思路

在这里插入图片描述

class Solution {
    public void nextPermutation(int[] nums) {
        // 1. 先找拐点前的i
        int i = 0 ;
        int len = nums.length;
        for(i = len-2 ; i >= 0;i--){
            if(nums[i] < nums[i+1]) break;
        }
        // 不存在 直接 reverse
        if(i == -1){
            int L = 0;
            int R  = len-1;
            while(L<R){
                swap(nums,L++,R--);
            }
            return;
        }

        // 找到第一个 略大
        int j = len-1;
        for( ; j > i ;j--){
            if(nums[j] > nums[i]) break;
        }

        // 交换 i 和 j
        swap(nums,i,j);
        // reverse [i+1,len-1];
        int L  = i+1;
        int R = len-1;
        while(L<R){
            swap(nums,L++,R--);
        }
    }

    private void swap(int[] nums,int i,int j){
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}

3- ACM 实现

public class nextP {

    public static void nextP(int[] nums){
        //1. 先找拐点前一个 i
        int i = 0;
        int len = nums.length;
        for(i = len-2 ; i >=0 ;i++){
            if(nums[i] < nums[i+1]) break;
        }

        // 如果 i == -1 直接 reverse
        if(i==-1){
            int L = 0;
            int R = len-1;
            while(L<R){
                swap(nums,L++,R--);
            }
            return;
        }


        // 找到 j
        int j =len-1;
        for(; j>i;j--){
            if(nums[j] > nums[i]) break;
        }
        // 交换 i 和 j
        swap(nums,i,j);

        // 3. 翻转 [i+1,len-1]
        int L = i+1;
        int R = len-1;
        while (L < R){
            swap(nums,L++,R--);
        }


    }

    private static void swap(int[] nums,int i ,int j){
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String input = sc.nextLine();
        input = input.replace("[","").replace("]","");
        String[] parts = input.split(",");
        int[] nums = new int[parts.length];
        for(int i= 0 ; i < nums.length;i++){
            nums[i] = Integer.parseInt(parts[i]);
        }
        nextP(nums);
        System.out.println("结果是");
        for(int i : nums){
            System.out.print(i+" ");
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值