数组-下一个排列

一、题目描述

二、解题思路

1.反向遍历当前排列,比如 排列A=[a,b,c,d,e,f...] ,当遍历到e时,说明以 a,b,c,d,e为前缀的排列中不存在A排列的下一个排列。

2.把e(位置设为idx)和后面的元素作比较:

        2.1 如果有大于e的元素,找出这些里面最小的数,跟e交换位置;将 [idx,length-1] 位置元素升序排序,得到的排列就是A的下一排列。

        2.2 如果没有则继续反向遍历。

3.当反向遍历完成并且没有发生元素位置交换时,说明没有排列A的下一个排列,将A排列元素从头到尾升序排序返回。

三、代码实现

import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @return int整型一维数组
     */
    public int[] nextPermutation (int[] nums) {
        if(nums.length<=1){
            return nums;
        }
        //从数组后面往前找
        int fidx=0,sidx=0;
        for(int i=nums.length-2;i>=0;i--){
            int nownum=nums[i];
            int overnownum=9999;
            for(int j=i+1;j<nums.length;j++){
                if(nums[j]>nownum){
                    if(overnownum>nums[j]){
                        overnownum=nums[j];
                        sidx=j;
                    }
                }
            }
            if(overnownum!=9999){//说明找到大于当前第i个位置的最小值了
                fidx=i;
                break;
            }
        }
        if(fidx!=0){//将fidx和sidx数值交换
            int tmpnum=nums[fidx];
            nums[fidx]=nums[sidx];
            nums[sidx]=tmpnum;
            fidx++;
        }
        //因为fidx=0时表示没有找到最大的数组排列,所以fidx=0恰好是对整个数组进行升序排序
        //从fidx排序(这里使用选择排序)
        for(int idx=fidx;idx<nums.length-1;idx++){
            int nownum=nums[idx];
            int minidx=9999;
            for(int pdx=fidx+1;pdx<nums.length;pdx++){
                if(nownum>nums[pdx]){
                    minidx=pdx;
                    nownum=nums[pdx];
                }
            }
            if(minidx!=9999){
                nums[minidx]=nums[fidx];
                nums[fidx]=nownum;
            }
        }
        return nums;
    }
}

四、刷题链接

下一个排列_牛客题霸_牛客网

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值