556. Next Greater Element III

49 阅读1分钟

image.png

思路

  • 找到一对「较小数」与「较大数」的组合为与,满足「较小数」尽量靠右,而「较大数」尽可能小。
  • 从后往前找到第一个降序的数字,作为较大数,替换他
    • 这个数字后面为升序,所以,从这个位置开始往后构成的数字已经是最大
  • 从后往前找第一个比替换数大的数字,作为较小数,swap
  • 后段必为降序,reverse一下再

image.png

class Solution {
    public int nextGreaterElement(int n) {
        char[] arr = (n + "").toCharArray();
        // 从后往前找第一个降序数 2543,找2
        int i = arr.length - 1;
        while (i - 1 >= 0 && arr[i - 1] >= arr[i]) {
            i--;
        }
        // 完全降序的输入,比如 321
        if (i == 0) {
            return -1;
        }
        
        //此时要找的第一个降序数为arr[i-1]

        // 从后往前找第一个比 arr[i - 1]大的数
        int j = arr.length - 1;
        while (j >= i  && arr[j] <= arr[i - 1]) {
            j--;
        }

        // 此时要找的数在arr[j]

        // 交换这两个数
        swap(arr, i - 1, j);

        // 把后半段弄成升序的
        reverse(arr, i, arr.length - 1);

        try {
            return Integer.parseInt(new String(arr)); 
        } catch (Exception e) {
            return -1; //防止溢出
        }
    }

    public void swap(char[] arr, int m, int n) {
        char tmp = arr[m];
        arr[m] = arr[n];
        arr[n] = tmp;
    }
    
    public void reverse(char[] arr, int start, int end) {
        while (start < end) {
            swap(arr, start, end);
            start++;
            end--;
        }
    }
}