670. 最大交换

255 阅读2分钟

题目

image.png

方法一

  • 核心就一句话:就是把第一个小数和它后面最大的大数进行交换, 小数要尽量在高位,大数尽量在低位。
  • 计算最后一次出现的数的索引。然后,从左到右扫描数字时,如果将来有较大的数字,我们将用最大的数字交换;如果有多个这样的数字,我们将用最开始遇到的数字交换。
class Solution {
    public int maximumSwap(int num) {
        String str = String.valueOf(num);
        char[] arr = str.toCharArray(); // num转为数组

        // 用于记录每个数字最后一次出现在arr中的索引
        int[] last = new int[10]; 
        for (int i = 0; i < arr.length; i++) {
            last[arr[i] - '0'] = i;
        }

        // 从左向右扫描,找到当前位置右边的最大的数字并交换
        for (int i = 0; i < arr.length; i++) {
            for (int j = last.length - 1; j >= 0; j--) {// 反着来找最大
                if (j > arr[i] - '0' && last[j] > i) {// 大数要出现在当前数字的右边
                    swap(arr, i, last[j]);
                    return Integer.parseInt(new String(arr));// 直叫唤一次
                } 
            }
        }

        return num; //无需交换
    }
    
    public void swap(char[] arr, int m, int n) {
        char tmp = arr[m];
        arr[m] = arr[n];
        arr[n] = tmp;
    }
}

方法二

  • 将num转换为数组
  • 拷贝数组并排序(升序),得到arrSorted
  • 从arrSorted最大值开始依次和arr比较,找到第一个不相等的数字在arr中位置,即应该被换位更大数字的位置。
  • 再扫一遍arr,找到那个更大数字的位置,swap。
  • 注意拷贝数组不能直接=,应该用arrNew = Arrays.copyOf(oldArr, length)
class Solution {
    public int maximumSwap(int num) {
        String str = String.valueOf(num);
        int length = str.length();
        char[] arr = str.toCharArray();
        // char[] arrSorted = arr;
        char[] arrSorted = Arrays.copyOf(arr, length);//正确的拷贝数组的方法
        Arrays.sort(arrSorted);//升序
        //找小数在原数组的index,并找到大数numBig
        int indexSmall = -1;
        int numBig = -1;
        for (int i = 0; i < length; i++) {
            if (arrSorted[length - 1 - i] != arr[i]) {//注意反序比较
                numBig = arrSorted[length - 1 - i];
                indexSmall = i;//小的
                break;
            }
        }
        //arr已经是最大数了,返回原数
        if (indexSmall == -1) {
            return num;
        }
        //找大数在原数组中的index,找最靠后的那个
        int indexBig = -1;
        for (int i = 0; i < length; i++) {
            if (arr[i] == numBig) {
                indexBig = i;
                // break;要找在最远处的,比如98368
            }
        }
        char tmp = arr[indexBig];
        arr[indexBig] = arr[indexSmall];
        arr[indexSmall] = tmp;
        
        int res = 0;
        for (int i = 0; i < length; i++) {
            res = res * 10 + arr[i] -'0';
        }
        return res;
    }
}