670. 最大交换

最大交换

  • 题目描述
  • 尝试做法
  • 推荐做法

题目描述

给定一个非负整数,你至多可以交换一次数字中的任意两位。返回你能得到的最大值。

示例 1 :

输入: 2736
输出: 7236
解释: 交换数字2和数字7。
示例 2 :

输入: 9973
输出: 9973
解释: 不需要交换。
注意:

给定数字的范围是 [0, 108]

尝试做法

class Solution {
    public int maximumSwap(int num) {
        if(num < 12) return num;
        boolean change = false;
        String str = String.valueOf(num);
        int temp1 = 0, temp2 = 1;
        StringBuilder sb = new StringBuilder();
        while(temp1 < str.length()){
            int max = temp1;
            for(int i = str.length() - 1; i > temp1; --i){
                if(str.charAt(i) > str.charAt(max)) max = i;
            }
            if(str.charAt(temp1) < str.charAt(max)){
                change = true;
                temp2 = max;
                break;
            }
            ++temp1;
        }
        if(change){
            for(int i = 0; i < str.length(); ++i){
                if(i == temp1){
                    sb.append(str.charAt(temp2));
                    continue;
                }
                if(i == temp2){
                    sb.append(str.charAt(temp1));
                    continue;
                }
                sb.append(str.charAt(i));
            }
            return Integer.parseInt(sb.toString());
        }else{
            return num;
        }
    }
}

实话实说,做完感觉我这做法应该算效率低的,没想到
670. 最大交换_第1张图片
看上去还行?
不过应该还有更好的方法。
总体的思路是一个指针从前往后找到第一个可以换的较小数,因为高位的数增加,对整体增加影响最大。
另一个指针从后往前找,找到最大的数,因为低位数变小,对整体变小影响最小。如果大于第一个指针的数,那么就开始交换。

推荐做法

class Solution {
    public int maximumSwap(int num) {
        char[] s = Integer.toString(num).toCharArray();
        int maxIdx = s.length - 1;
        int p = -1, q = 0;
        for (int i = s.length - 2; i >= 0; i--) {
            if (s[i] > s[maxIdx]) { // s[i] 是目前最大数字
                maxIdx = i;
            } else if (s[i] < s[maxIdx]) { // s[i] 右边有比它大的
                p = i;
                q = maxIdx; // 更新 p 和 q
            }
        }
        if (p == -1) { // 这意味着 s 是降序的
            return num;
        }
        char temp = s[p];
        s[p] = s[q];
        s[q] = temp; // 交换 s[p] 和 s[q]
        return Integer.parseInt(new String(s));
    }
}

作者:灵茶山艾府
链接:https://leetcode.cn/problems/maximum-swap/solutions/2614470/yi-ci-bian-li-jian-ji-xie-fa-pythonjavac-c9b1/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

从后往前,可以在找到满足条件的指针的同时,减少时间复杂度

class Solution {
    public int maximumSwap(int num) {
        List<Integer> list = new ArrayList<>();
        while (num != 0) {
            list.add(num % 10); num /= 10;
        }
        int n = list.size(), ans = 0;
        int[] idx = new int[n];
        for (int i = 0, j = 0; i < n; i++) {
            if (list.get(i) > list.get(j)) j = i;
            idx[i] = j;
        }
        for (int i = n - 1; i >= 0; i--) {
            if (list.get(idx[i]) != list.get(i)) {
                int c = list.get(idx[i]);
                list.set(idx[i], list.get(i));
                list.set(i, c);
                break;
            }
        }
        for (int i = n - 1; i >= 0; i--) ans = ans * 10 + list.get(i);
        return ans; 
    }
}

作者:宫水三叶
链接:https://leetcode.cn/problems/maximum-swap/solutions/1820215/by-ac_oier-jxmh/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

也可以先遍历一遍,记录大小信息,利用空间换时间。

你可能感兴趣的:(力扣刷题记录,算法,leetcode)