【LeetCode】给定任意一个自然数,获取它重新排列后,下一个比它大的自然数

题目:

//    给定任意一个自然数,获取它重新排列后,下一个比它大的自然数,要求时间复杂度O(n)。例如:
//    给定1233,它的下一个是1323;
//    给定1323,它的下一个是1332;
//    给定9876,它的下一个不存在;
//    请设计一个函数,完成此功能。(语言不限)

 

具体解决思路在注释中写的很详细了

package ChuJiSuanFa.src;

import java.util.ArrayList;

public class exam
{
    public static void main(String[] args)
    {
        System.out.println("题目2:");
        int num = 1323;
        String result = exam2(num);
        System.out.println("数字 " + num + "比他大的排列为" + result);
    }

    //    给定任意一个自然数,获取它重新排列后,下一个比它大的自然数,要求时间复杂度O(n)。例如:
//    给定1233,它的下一个是1323;
//    给定1323,它的下一个是1332;
//    给定9876,它的下一个不存在;
//    请设计一个函数,完成此功能。(语言不限)
    static String exam2(int num)
    {
//        创建空数组
        ArrayList<Integer> nums = new ArrayList<>();
//        分解自然数并放入数组
        while ((num % 10) > 0) {
            int tmp = num % 10;
            num = num / 10;
            nums.add(0, tmp);
        }
//        为了和原数接近,我们需要尽量保持高位不变,低位在最小的范围内变换顺序。

//        0.从后向前查看逆序区域,找到逆序区域的前一位,也就是数字置换的边界
        int criticalPoint = findCriticalPoint(nums);
//        1.首先检查是否为最大值
        if (criticalPoint == -1) {
            return "不存在";
        }
//        2.把逆序区域的前一位和逆序区域中刚刚大于它的数字交换位置并把原来的逆序区域转为顺序
        return reorder(nums, criticalPoint).toString();
    }

    static int findCriticalPoint(ArrayList<Integer> nums)
    {
        for (int i = nums.size() - 1; i > 0; i--) {
            if (nums.get(i) > nums.get(i - 1)) {
//                如果找到临界值,返回那个值
                return i;
            }
        }
//        没找到,代表该数组每个数都比后面的数大也就是逆序排列
        return -1;
    }

    static ArrayList<Integer> reorder(ArrayList<Integer> nums, int index)
    {
        int left = nums.get(index - 1);
        for (int i = nums.size() - 1; i >= index; i--) {
            int right = nums.get(i);
            if (left < right) {
                nums.set(index - 1, right);
                nums.set(i, left);
                break;
            }
        }
        for (int i = index, j = nums.size() - 1; i < j; i++, j--) {
            int temp = nums.get(i);
            nums.set(i, nums.get(j));
            nums.set(j, temp);
        }
        return nums;
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值