LintCode1095: Maximum Swap (并不简单)

  1. Maximum Swap
    中文English
    Given a non-negative integer. You could choose to swap two digits of it. Return the maximum valued number you could get.

Example
Example 1:

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

Input: 9973
Output: 9973
Explanation: No swap.
Notice
The given number is in the range of [0, 10^8]

解法1:
思路。先把digits放到数组里面。然后找出最大值和第2大值。
若第1个数字不是最大值,则将最大值和第1个数字交换即可。
若第1个数字是最大值,则考虑将第2个数字和第2大值交换。但这里又要分情况讨论:

  1. 第2大值就是第2个数字,则此时要从第3个数字开始往后找,直到找到一个数字不是第2大值,则将第2大值与其交换。
    举例:98386,变成numbers=[6,8,3,8,9]。注意这里顺序相反。
    maxDigit=9, maxDigitIndex=4 此时maxDigitiIndex=len-1,则考虑secondMaxDigit。
    secondMaxDigit=8, secondMaxDigit=1 (注意查找是从numbers[0]开始的)。此时numbers[len-2]也是8,那就从numbers[len-3]也就是3往前找,直到找到第一个不是8的元素与numbers[1]相交换。
    有个特殊情况是98888,numbers=[8,8,8,8,9],则找不到一个不是8的元素,那也没关系,就不用交换了。
  2. 注意找第2大数的方法。
  3. 一位数的情况就直接返回即可。
    代码如下:
class Solution {
public:
    /**
     * @param num: a non-negative intege
     * @return: the maximum valued number
     */
    int maximumSwap(int num) {
        if (num < 10) return num;
        
        vector<int> numbers;
        
        while(num) {
            numbers.push_back(num % 10);
            num /= 10;
        }
        
        int len = numbers.size();
        
        int maxDigit = 0, maxDigitIndex = 0, secondMaxDigit = 0, secondMaxDigitIndex = 0;
        for (int i = 0; i < len; ++i) {
            if (secondMaxDigitIndex < numbers[i]) {
                secondMaxDigit = numbers[i]; 
                secondMaxDigitIndex = i;
                if (secondMaxDigit > maxDigit) {
                    swap(maxDigit, secondMaxDigit);
                    swap(maxDigitIndex, secondMaxDigitIndex);
                }
            }
        }

        if (maxDigitIndex == len - 1) {
            if (numbers[len - 2] == secondMaxDigit && len > 3) {
                for (int i = len - 3; i >= 0; --i) {
                    if (numbers[i] != secondMaxDigit) {
                        swap(numbers[secondMaxDigitIndex], numbers[i]);
                        break;
                    }
                }
            } else {
                swap(numbers[secondMaxDigitIndex], numbers[len - 2]);
            }
        } else {
            swap(numbers[maxDigitIndex], numbers[len - 1]);
        }

        num = 0;
        for (int i = len - 1; i >= 0; --i) {
            num = num * 10 + numbers[i];
        }
        
        return num;
    }
};

解法2:看到网上的解法,比我的解法好很多。
思路:对每一个数字a,找出后面是否有比它大的数b,如果有,找到b出现的最后位置并与a对调。

举例:632747。此时应找到第2个7与6对调。
注意:
1)可以用to_string(num)和stoi(string)函数省时间。

代码如下:

class Solution {
public:
    /**
     * @param num: a non-negative intege
     * @return: the maximum valued number
     */
    int maximumSwap(int num) {
        vector<int> pos(10, -1);
        string number = to_string(num);
        int n = number.size();
        for (int i = 0; i < n; i++) {
            pos[number[i] - '0'] = i;
        }
        
        for (int i = 0; i < n; i++) {
            for (char j = '9'; j > number[i]; j--) {
                if (pos[j - '0'] > i) {
                    swap(number[i], number[pos[j - '0']]);
                    return stoi(number);
                }
            }
        }
        
        return num;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值