241012-556-下一个更大元素III

39 阅读1分钟

给你一个正整数 n ,请你找出符合条件的最小整数,其由重新排列 n ****中存在的每位数字组成,并且其值大于 n 。如果不存在这样的正整数,则返回 -1 。

注意 ,返回的整数应当是一个 32 位整数 ,如果存在满足题意的答案,但不是 32 位整数 ,同样返回 -1 。

示例 1:

输入: n = 12
输出: 21

示例 2:

输入: n = 21
输出: -1

提示:

  • 1 <= n <= 231 - 1
public int nextGreaterElement(int n) {
        //求最小整数,从尾部动手对数值影响最小
        //如果要移动i,向左找出最近的第一个比它小的数交换,这样得到的是只移动i的最小值
        //我们发现只要从末尾找到第一个这样的数字之后左边部分就可以固定了(再怎么操作左边也不可能比这个数小)
        //然后最重要的一步,把右半部分递增排序,可以得到左半部固定条件下的最小数字
        //附近最值——stack
        String num = String.valueOf(n);
        char[] chars = num.toCharArray();
        ArrayDeque<Integer> stack = new ArrayDeque<>();
        int max = Integer.MAX_VALUE;
        char[] res = chars;
        for (int i = chars.length - 1; i >= 0; i--) {
            if (!stack.isEmpty() && chars[stack.peek()] > chars[i]) {
                //此时找到了交换位置,需要从栈里选比chars[i]刚好大的元素来交换
                Integer pop = stack.peek();
                while( !stack.isEmpty() && chars[stack.peek()] > chars[i]){
                    pop = stack.pop();
                }
                res = swap(num, pop, i);
                //注意别把i也排序了
                Arrays.sort(res, i + 1, res.length);
                break;
            }
            stack.push(i);
        }
        int r = -1;
        try {
            r = num.equals(String.valueOf(res)) ?
                    -1 : Integer.parseInt(String.valueOf(res));
        }catch (Exception e){
            // 超出integer.MAX_VALUE则捕获后默认-1
            //  e.printStackTrace();
        }
        return r;
    }

    public char[] swap(String num, int i, int j) {
        char[] chars = num.toCharArray();
        char tmp = chars[j];
        chars[j] = chars[i];
        chars[i] = tmp;
        return chars;
    }
}