【LeetCode-556】556. 下一个更大元素 III

556. 下一个更大元素 III

题目描述

给定一个32位正整数 n,你需要找到最小的32位整数,其与 n 中存在的位数完全相同,并且其值大于n。如果不存在这样的32位整数,则返回-1。

在这里插入图片描述

类似于求:LeetCode31题——下一个排列

参考思路:线性扫描,时间复杂度O(n)

算法思想:把 n 转为为字符数组 arr ,然后从后往前看,找到第一个下降的位置 i,然后让再从后往前找到第一个比 i 位置的值大的数,交换这两个位置,再逆序i后面的所有字符。

举例理解:

n: 12544321
n: 12|544321
从后往前看第一个严格下降的数是2
然后再从后往前看第一个比2大的数是3
于是交换23
得到13|544221
最后逆序544221这一段

得到最终答案13122445
class Solution {
    public int nextGreaterElement(int n) {
        // base case
        if(n <= 0 || n == Integer.MAX_VALUE) {
            return -1;
        }
        char[] arr = String.valueOf(n).toCharArray();
        int len = arr.length;

        int start = -1;
        for(int i = len - 1; i >= 1; i--) {
            // 从后往前看第一个不满足递增的数
            if(arr[i] > arr[i - 1]) {
                start = i - 1;
                break;
            }
        }
        if(start == -1) {
            return -1;
        }
        
        // 从后往前找第一个大于等于arr[start]的数
        for(int j = len - 1; j > start; j--) {
            if(arr[j] > arr[start]) {
                swap(arr, start, j);
                break;
            }
        }
        
        // 将start~len-1进行逆序
        for(int p = start + 1, q = len - 1; p < q; p++, q--) {
            swap(arr, p, q);
        }

        long sum = 0;
        for(int k = 0; k < len; k++) {
            sum = sum * 10 + (arr[k] - '0');
        }
        return sum > Integer.MAX_VALUE ? -1 : (int)sum;
    }

    public void swap(char[] arr, int i, int j) {
        char ch = arr[j];
        arr[j] = arr[i];
        arr[i] = ch;
    }
}

时间复杂度是O(n):最多扫描两次字符串
空间复杂度是O(n):使用了长度为n的数组存储数字的每个位

参考博客

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值