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:

  1. The given number is in the range [0, 108]

这道题给了一个数字,我们有一次机会可以置换该数字中的任意两位,让返回置换后的最大值,当然如果当前数字就是最大值,也可以选择不置换,直接返回原数。那么最简单粗暴的方法当然就是将所有可能的置换都进行一遍,然后更新结果 res,取其中较大的数字,这样一定会得到置换后的最大数字,这里使用了整型数和字符串之间的相互转换,参见代码如下:

解法一:

class Solution {
public:
int maximumSwap(int num) {
string str = to_string(num);
int res = num, n = str.size();
for (int i = ; i < n; ++i) {
for (int j = i + ; j < n; ++j) {
swap(str[i], str[j]);
res = max(res, stoi(str));
swap(str[i], str[j]);
}
}
return res;
}
};

下面这种解法是一种更优解,思路是这样的,由于希望置换后的数字最大,那么肯定最好的高位上的小数字和低位上的大数字进行置换,比如题目汇总的例子1。而如果高位上的都是大数字,像例子2那样,很有可能就不需要置换。所以需要找到每个数字右边的最大数字(包括其自身),这样再从高位像低位遍历,如果某一位上的数字小于其右边的最大数字,说明需要调换,由于最大数字可能不止出现一次,这里希望能跟较低位的数字置换,这样置换后的数字最大,所以就从低位向高位遍历来找那个最大的数字,找到后进行调换即可。比如对于 1993 这个数:

1 9 9 3

9 9 9 3  (back数组)

9 9 1 3

我们建立好back数组后,从头遍历原数字,发现1比9小,于是从末尾往前找9,找到后一置换,就得到了 9913。

解法二:

class Solution {
public:
int maximumSwap(int num) {
string res = to_string(num), back = res;
for (int i = back.size() - ; i >= ; --i) {
back[i] = max(back[i], back[i + ]);
}
for (int i = ; i < res.size(); ++i) {
if (res[i] == back[i]) continue;
for (int j = res.size() - ; j > i; --j) {
if (res[j] == back[i]) {
swap(res[i], res[j]);
return stoi(res);
}
}
}
return stoi(res);
}
};

下面这种解法建了十个桶,分别代表数字0到9,每个桶存该数字出现的最后一个位置,也就是低位。这样从开头开始遍历数字上的每位上的数字,然后从大桶开始遍历,如果该大桶的数字对应的位置大于当前数字的位置,说明低位的数字要大于当前高位上的数字,那么直接交换这两个数字返回即可,其实核心思路跟上面的解法蛮像的,参见代码如下:

解法三:

class Solution {
public:
int maximumSwap(int num) {
string str = to_string(num);
vector<int> buckets(, );
for (int i = ; i < str.size(); ++i) {
buckets[str[i] - ''] = i;
}
for (int i = ; i < str.size(); ++i) {
for (int k = ; k > str[i] - ''; --k) {
if (buckets[k] <= i) continue;
swap(str[i], str[buckets[k]]);
return stoi(str);
}
}
return num;
}
};

我们也可以进一步的优化空间,实际上只关注两个需要交换的位置即可,即高位上的小数字和低位上的大数字,分别用 pos1 和 pos2 指向其位置,均初始化为 -1,然后用一个指针 mx 指向低位最大数字的位置,初始化为 n-1,然后从倒数第二个数字开始往前遍历,假如 str[i] 小于 str[mx],说明此时高位上的数字小于低位上的数字,是一对儿潜在可以交换的对象(但并不保证上最优解),此时将 pos1 和 pos2 分别赋值为 i 和 mx;若 str[i] 大于 str[mx],说明此时 str[mx] 不是低位最大数,将 mx 更新为 i。循环结束后,若 pos1 不为 -1,说明此时找到了可以交换的对象,而且找到的一定是最优解,直接交换即可,参见代码如下:

解法四:

class Solution {
public:
int maximumSwap(int num) {
string str = to_string(num);
int n = str.size(), mx = n - , pos1 = -, pos2 = -;
for (int i = n - ; i >= ; --i) {
if (str[i] < str[mx]) {
pos1 = i;
pos2 = mx;
} else if (str[i] > str[mx]) {
mx = i;
}
}
if (pos1 != -) swap(str[pos1], str[pos2]);
return stoi(str);
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/670

类似题目:

Create Maximum Number

参考资料:

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

https://leetcode.com/problems/maximum-swap/discuss/107068/Java-simple-solution-O(n)-time

https://leetcode.com/problems/maximum-swap/discuss/107153/simple-c-using-stdstring-and-stdstoi

https://leetcode.com/problems/maximum-swap/discuss/107084/C%2B%2B-3ms-O(n)-time-O(n)-space-DP-solution

https://leetcode.com/problems/maximum-swap/discuss/107073/C%2B%2B-one-pass-simple-and-fast-solution%3A-1-3ms-O(n)-time

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Maximum Swap 最大置换的更多相关文章

  1. [LeetCode] 670. Maximum Swap 最大置换

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

  2. LeetCode Maximum Swap

    原题链接在这里:https://leetcode.com/problems/maximum-swap/description/ 题目: Given a non-negative integer, yo ...

  3. LeetCode:Maximum Depth of Binary Tree_104

    LeetCode:Maximum Depth of Binary Tree [问题再现] Given a binary tree, find its maximum depth. The maximu ...

  4. LeetCode Maximum Product Subarray(枚举)

    LeetCode Maximum Product Subarray Description Given a sequence of integers S = {S1, S2, . . . , Sn}, ...

  5. LeetCode——Maximum Depth of Binary Tree

    LeetCode--Maximum Depth of Binary Tree Question Given a binary tree, find its maximum depth. The max ...

  6. LC 670. Maximum Swap

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

  7. [LeetCode] Maximum Product Subarray 求最大子数组乘积

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  8. [Swift]LeetCode670. 最大交换 | Maximum Swap

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

  9. 670. Maximum Swap

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

随机推荐

  1. WEB页面异步调用场景测试

    在我们测试异步调用前,我们首先弄清楚异步调用到底是什么? 异步调用的定义:一个可以无需等待被调用函数的返回值就让操作继续进行的方法, 举一个形象的例子就是:领导给A分配了一个任务, 然后领导就干其他事 ...

  2. alpha冲刺第七天

    一.合照 二.项目燃尽图 三.项目进展 问答界面问答内容呈现 设置里的帐号设置呈现 能爬取教务处网站的内容保存到本地数据库 四.明日规划 继续完善各个内容的界面呈现 查找关于如何自动更新爬取内容 搜索 ...

  3. Linux下进程间通信的六种机制详解

    linux下进程间通信的几种主要手段:        1.管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具 ...

  4. 在深度linux下安装pip3与jupyter

    前言 以下安装说明基于已经正确安装python3 文件下载 https://pypi.python.org/pypi/pip 下载pip-9.0.1.tar.gz (md5, pgp)文件 安装准备工 ...

  5. 创建带缩进的XML

    from xml.etree import ElementTree as ET from xml.dom import minidom root = ET.Element('}) son=ET.Sub ...

  6. PM2使用心得

    PM2是node进程管理工具,可以利用它来简化很多node应用管理的繁琐任务,如性能监控.自动重启.负载均衡等,而且使用非常简单. 安装 npm install -g pm2 常用命令 $ npm i ...

  7. EasyUI中Tabs添加远程数据的方法。

    tabs加载远程数据: $(function () { $("#btnquery").click(function () { if (!$("#tcontent" ...

  8. 彻底搞懂shell的高级I/O重定向

    本文目录: 1.1 文件描述符(file description,fd) 1.2 文件描述符的复制 1.3 重定向顺序很重要:">file 2>&1"和&quo ...

  9. 初学者如何查阅自然语言处理(NLP)领域学术资料

    1. 国际学术组织.学术会议与学术论文 自然语言处理(natural language processing,NLP)在很大程度上与计算语言学(computational linguistics,CL ...

  10. linux下安装redis和phpredis扩展

    一.安装redis 1.下载redis-3.2.3.tar.gz wget http://download.redis.io/releases/redis-3.2.3.tar.gz 2.解压redis ...