<LeetCode> 31.下一个排列

下一个字典序的产生思想

当前字典序和下一个字典序一定是共同前缀的
从最后一位往前递归,保证后缀子串是从小到大有序的
(1) 比较当前nums[cur]和后缀子串,如果后缀子串中存在比当前nums[cur]大的数,则该nums[cur]与后缀子串组成的新的后缀子串存在更大的字典序,只需要找到原子串中比nums[cur]第一个大的元素,并与nums[cur]交换,即是下一个字典序.则完成任务,一路返回即可.
(2)如果不存在比当前nums[cur]大的数,则表明从最后一位到cur的位置都是最大字典序,则把该数插入到最后位置,保证后缀子串有序.

为什么要维护后缀子串为有序递增?是为了保证新后缀为最小字典序.这样当有可交换的cur时,直接交换cur和可交换的数即为下一个字典序.


“1,4,2,3,1”
(1) '1' ,后缀没有子串,返回上一层
(2) '3',后缀'1', 3>1 , 无下一个字典序, 插入3 后缀子串"1,3"

(3)'2',后缀'1,3', 2>1,2<3,交换2,3 => 1,4,3,1,2 .  找到下一个字典序,一路返回.

class Solution {
    public void nextPermutation(int[] nums) {
        if(nums.length<=1) return;
        permutation(nums,0,nums.length-1);
    }
    
    private boolean permutation(int[] nums, int s, int e){
        if (e-s<=0) return false;
        boolean flag  = permutation(nums,s+1, e);
        if(flag) return flag;
        for(int i=s+1;i<=e;i++)
        {
            if(nums[i]>nums[s]){
                swap(nums, i, s);
                return true;
            }
            
        }
        for(int i=s;i<e;i++){
            if(nums[i]>nums[i+1]){
                swap(nums,i,i+1);
            }

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

时间复杂度O(n),空间复杂度O(n) 运行时间超过100%,运行空间超过78%

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值