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. 利用CSS3制作网页动画

    如何在网页中实现动画效果动态图片 flashjavascriptcss3变形是一些效果的集合如平移 旋转 缩放 倾斜效果每个效果都可以称为变形(transfrom) 它们可以分别操控元素发生平移.旋转 ...

  2. Java基础学习笔记十六 集合框架(二)

    List List接口的特点: 它是一个元素存取有序的集合.例如,存元素的顺序是11.22.33.那么集合中,元素的存储就是按照11.22.33的顺序完成的. 它是一个带有索引的集合,通过索引就可以精 ...

  3. 【R语言系列】作图入门示例一

    假设有如下数据,我们使用plot函数作图 月龄 体重 月龄 体重  1 4.4 9 7.3 3 5.3 3 6.0 5 7.2 9 10.4 2 5.2 12 10.2 11 8.5 3 6.1 R语 ...

  4. [福大软工] W班 软工实践原型设计—成绩公布

    作业地址 https://edu.cnblogs.com/campus/fzu/FZUSoftwareEngineering1715W/homework/909 作业要求 详见作业地址 存在问题 1. ...

  5. Alpha冲刺第十二天

    Alpha冲刺第十二天 站立式会议 项目进展 项目核心功能,如学生基本信息管理模块,学生信用信息模块,奖惩事务管理模块等等都已完成,测试工作大体结束. 问题困难 项目结束后对项目的阶段性总结缺乏一定的 ...

  6. 使用genstring和NSLocalizedString实现App文本的本地化

    OS提供了简便的方法来实现本地化,其中用的最多的就是NSLocalizedString. 首先查看下NSLocalizedString是什么: #define NSLocalizedString(ke ...

  7. AWS中的Internet 网关

    nternet 网关是一种横向扩展.支持冗余且高度可用的 VPC 组件,可实现 VPC 中的实例与 Internet 之间的通信.因此它不会对网络流量造成可用性风险或带宽限制. Internet 网关 ...

  8. 要学好JAVA要注意些什么?

    从自学开始到参加系统的学习JAVA已经差不多有1个月了的时间了,在这段时间以前我也和很多人一样在网上盲目的搜罗一些视频来自己啃,随着时间的积累,对JAVA的认识也有了一定的提升,之前可能因为在IT咨询 ...

  9. JAVA_SE基础——5.第一个Java程序HelloWorld&注释的应用

    配置完JDK&环境变量后,我们就可以开始写程序了,那么程序怎么写呢,用什么工具呢,我建议 为了方便学习,我们最好在一个磁盘下建立一个专门的文件来写java程序,比如就在D盘下建立一个名为&qu ...

  10. 新概念英语(1-13)A new dress

    What colour is Anna's hat? A:What colour is your new dress? B:It's green.Come upstairs and see it. A ...