LeetCode-670:Maximum Swap (交换数字得最大整数) -- medium

参考:https://blog.csdn.net/Koala_Tree/article/details/78476337 ,写的特别好。

我的代码实现如下:

Question
Given a non-negative integer, you could swap two digits at most once to get the maximum valued number. Return the maximum valued number you could get.

Example 1:

Input: 2736
Output: 7236
Explanation: Swap the number 2 and the number 7.

Example 2:

Input: 9973
Output: 9973
Explanation: No swap.
Note: 
* The given number is in the range [0, 108].

问题解析:

给定非空非负整数,最多交换其中的两个数字,得到最大的整数,返回最大整数。

Answer
Solution 1:
个人解决方案:

首先以例子分析要交换的特性,我们会发现,当整数中的所有数字均按照非递增的顺序排序,那么这个整数就是最大整数,不需要进行交换;
所以根据上面的分析,我们需要寻找整数中数字出现不符合非递增规则的分裂点,记录违规的分裂点;
在分裂点的后半部分寻找最大的数字,并且位置越靠后的数字相对前面与其相等的前面的数字交换的意义更大,也就是我们要求寻找digits[j] >= max,注意这里是>=;
在分裂点的前半部分从后向前寻找小于上一步找到的max的最大值;
将找到的两个位置数字进行交换,即可得到交换最大整数。
注意,为了进行操作,需先将整数转化为char数组,并在交换后转换回整数。
class Solution {
    public int maximumSwap(int num) {
        char[] digits = Integer.toString(num).toCharArray();

        if(digits.length == 1) return num;

        // 寻找不符合非递增顺序的分界线
        int split = 0;
        for (int i = 0; i < digits.length-1; i++){
            if (digits[i] < digits[i+1]){
                split = i+1;
                break;
            }
        }

        // 在分界线后面的部分寻找最大的值max
        char max = digits[split];
        int index1 = split;
        for (int j = split+1; j < digits.length; j++){
            if (digits[j] >= max){
                max = digits[j];
                index1 = j;
            }
        }

        // 在分界线前面的部分向前寻找小于max的最大值
        int index2 = split;
        for (int i = split-1; i >= 0; i--){
            if (digits[i] >= max){
                break;
            }
            index2--;
        }

        //交换两位找到的char
        char temp = digits[index1];
        digits[index1] = digits[index2];
        digits[index2] = temp;

        return Integer.valueOf(new String(digits));
    }
}

时间复杂度:O(n),空间复杂度:O(n)
Solution 2:
利用桶的思想。

利用indices桶数组记录数字0〜9的最后位置。
遍历整个整数变为char的数组,从左到右提取每一个数字;
对提取到的每一个数字检查是否存在比它更大的数字存在,故与桶的位置数字做比较(从9开始到当前数字);
如果,存在比提取的数字更大的桶,我们还需要确保这个较大数字的位置落后于桶数字所在的位置;
如果找到,则交换两个位置,转换数组并返回。
这种解法更加巧妙。
class Solution {
    public int maximumSwap(int num) {
        char[] digits = Integer.toString(num).toCharArray();
        int[] indices = new int[10];
        int result = num;
        for(int i = 0; i < digits.length; i++) {
            indices[digits[i] - '0'] = i;
        }
        for(int i = 0; i < digits.length-1; i++) {
            int digit = digits[i] - '0';
            for(int j = 9; j > digit; j--) {
                if(indices[j] > i) {
                    char temp = digits[i];
                    digits[i] = digits[indices[j]];
                    digits[indices[j]] = temp;
                    result = Integer.parseInt(new String(digits));
                    return result;
                }
            }
        }
        return result;
    }
}

时间复杂度:O(n),空间复杂度:O(n)
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值