670. Maximum Swap**

​https://leetcode.com/problems/maximum-swap/​

题目描述

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 670. Maximum Swap**_leetcode

C++ 实现 1

贪婪策略. 来自 LeetCode 的解答: ​​https://leetcode.com/problems/maximum-swap/solution/​

发现英文的表述更为精准, 这里引用一下:

Intuition

At each digit of the input number in order, if there is a larger digit that occurs later, we know that the best swap must occur with the digit we are currently considering.

Algorithm

We will compute 670. Maximum Swap**_搜索_02 the index 670. Maximum Swap**_git_03 of the last occurrence of digit 670. Maximum Swap**_搜索_04 (if it exists).

Afterwards, when scanning the number from left to right, if there is a larger digit in the future, we will swap it with the largest such digit; if there are multiple such digits, we will swap it with the one that occurs the latest.

概括来说, 依次访问 ​​num​​​ 中的每个数字, 比如访问到 ​​digits[i]​​​ 时, 如果后面还出现了更大的数字 ​​k​​​, 那么用 ​​k​​​ 来和 ​​digits[i]​​​ 交换, 就能获取最大的结果. 为此, 从 ​​[9, digits[i])​​​ 范围内搜索 ​​k​​.

下面代码中, 在 ​​pos​​​ 保存每个数字的索引, 需要注意的是, 如果 ​​num​​​ 存在相同的元素, 保存的是最远的元素的索引, 这样可以保证交换 670. Maximum Swap**_c++_05670. Maximum Swap**_搜索_06 时, 最后获得结果最大. 比如 ​​​1993​​​, 要用第二个 ​​9​​​ 来和 ​​1​​ 交换.

class Solution {
public:
int maximumSwap(int num) {
vector<int> pos(10, 0);
string digits = std::to_string(num);
// 如果有相同的数字, 那么保存最远的那个
for (int i = 0; i < digits.size(); ++ i)
pos[digits[i] - '0'] = i;
// 对每个位置上的数字 digits[i], 从 k = 9 开始搜索, 判断
// digits[i] 之后是否存在大于 digits[i] 的数字.
for (int i = 0; i < digits.size(); ++ i) {
int n = digits[i] - '0';
for (int k = 9; k > n; --k) {
if (pos[k] > i) { // pos[k] > i 保证满足条件的数字出现在 digits[i] 之后
std::swap(digits[i], digits[pos[k]]);
return std::stoi(digits);
}
}
}
return std::stoi(digits);
}
};