Maximum Swap LT670
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]
Idea 1. To get a biggest digit for each position, the digit need to swap with the biggest in the number, since it aims to get the maximum valued number, the digit (digits[i]) need to swap with the biggest digit on the right(digits[j] > digits[i], j > i), the digit needs to be the leftmost one which has a bigger digit on the right side. Since needs index to swap, build the maxIndex array. 从右往左建一个maxIndexArray, 再从左到右遍历 找到第一个digits[i] < digits[maxIndex[i]], swap(i, maxIndex[i]).
Note: right most maxIndex, if there are duplicates like 27736, 77236 > 72736
Time complexity: O(n) 2 scan, if string construction is O(n)
Space complexity: O(n)
class Solution {
public int maximumSwap(int num) {
char[] digits = Integer.toString(num).toCharArray();
int[] maxIndex = new int[digits.length];
maxIndex[digits.length-1] = digits.length-1;
for(int i = digits.length-2; i >=0; --i) {
maxIndex[i] = i;
if(digits[maxIndex[i]] - '0' <= digits[maxIndex[i+1]] - '0') {
maxIndex[i] = maxIndex[i+1];
}
}
for(int i = 0; i < digits.length; ++i) {
if(digits[i] - '0' < digits[maxIndex[i]] - '0') {
char c = digits[i];
digits[i] = digits[maxIndex[i]];
digits[maxIndex[i]] = c;
break;
}
}
return Integer.parseInt(new String(digits));
}
}
Idea 1.a, to avoid maxIndex array, record the maxIndex on the way, 1 scan from right to left
class Solution {
private void swap(char[] digits, int leftIndex, int rightIndex) {
char c = digits[leftIndex];
digits[leftIndex] = digits[rightIndex];
digits[rightIndex] = c;
}
public int maximumSwap(int num) {
char[] digits = Integer.toString(num).toCharArray();
int leftIndex = -1, rightIndex = -1;
int maxIndex = digits.length-1;
for(int i = digits.length-1; i >=0; --i) {
if(digits[i] > digits[maxIndex]) {
maxIndex = i;
}
else if(digits[i] < digits[maxIndex]) {
leftIndex = i;
rightIndex = maxIndex;
}
}
if(leftIndex == -1) {
return num;
}
swap(digits, leftIndex, rightIndex);
return Integer.parseInt(new String(digits));
}
}
Idea 1.c. Remove the use of toCharArray, convert to digit on the way from right to left.
Time complexity: O(n)
Space complexity: O(1)
class Solution {
public int maximumSwap(int num) {
int leftDigit = -1, rightDigit = -1;
int leftBase = 0, rightBase = 0;
int curr = num;
int maxDigit = -1;
int maxBase = 0;
int base = 1;
while(curr != 0) {
int digit = curr % 10;
if(digit > maxDigit) {
maxDigit = digit;
maxBase = base;
}
else if(digit < maxDigit) {
leftDigit = digit;
leftBase = base;
rightDigit = maxDigit;
rightBase = maxBase;
}
base = base * 10;
curr = curr/10;
}
if(leftDigit == -1) {
return num;
}
num = num - leftDigit*leftBase - rightDigit*rightBase
+ leftDigit* rightBase + rightDigit * leftBase;
return num;
}
}
Idea 2. 官方的妙法,数字只有0-9,建立一个数组记录每个数字出现在最右边的index(从左到右扫), 再从左到右扫,寻找第一个digits[i] < last[d] (d > digits[i] and last[d] > i), swap(digits, i, last[d]).
class Solution {
private void swap(char[] digits, int i, int j) {
char c = digits[i];
digits[i] = digits[j];
digits[j] = c;
}
public int maximumSwap(int num) {
char[] digits = Integer.toString(num).toCharArray();
int[] last = new int[10];
for(int i = 0; i < digits.length; ++i) {
last[digits[i] - '0'] = i;
}
for(int i = 0; i < digits.length; ++i) {
for(int d = 9; d > digits[i] - '0'; --d) {
if(last[d] > i) {
swap(digits, i, last[d]);
return Integer.valueOf(new String(digits));
}
}
}
return num;
}
}
Idea 3. 虽然也感觉和LT31 Next Permutation有相似的,没有找出规律,网上看到的妙法,从左到右找到第一个valley, 继续valley后找到最大值作为要交换的rightIndex, 然后再从左到右找一个小于最大值的作为leftIndex, swap(digits, leftIndex, rightIndex); LT31是从右到左找第一个peak, peak的左边是rightIndex, 再从右到左找第一个比digits[rightIndex]小的作为leftIndex, 最后交换就是了.
Note. duplicates, rightMost index like 27736, 77236 > 72736, 又犯了错,下次记住这个test case啊
class Solution {
private void swap(char[] digits, int i, int j) {
char c = digits[i];
digits[i] = digits[j];
digits[j] = c;
}
public int maximumSwap(int num) {
char[] digits = Integer.toString(num).toCharArray();
int rightIndex = 1;
while(rightIndex < digits.length && digits[rightIndex-1] >= digits[rightIndex]) {
++rightIndex;
}
if(rightIndex == digits.length) {
return num;
}
for(int i = rightIndex+1; i < digits.length; ++i) {
if(digits[i] >= digits[rightIndex]) {
rightIndex = i;
}
}
for(int i = 0; i < digits.length; ++i) {
if(digits[i] < digits[rightIndex]) {
swap(digits, i, rightIndex);
break;
}
}
return Integer.parseInt(new String(digits));
}
}
Maximum Swap LT670的更多相关文章
- LC 670. Maximum Swap
Given a non-negative integer, you could swap two digits at most once to get the maximum valued numbe ...
- [LeetCode] Maximum Swap 最大置换
Given a non-negative integer, you could swap two digits at most once to get the maximum valued numbe ...
- [Swift]LeetCode670. 最大交换 | Maximum Swap
Given a non-negative integer, you could swap two digits at most once to get the maximum valued numbe ...
- 670. Maximum Swap
Given a non-negative integer, you could swap two digits at most once to get the maximum valued numbe ...
- 670. Maximum Swap 允许交换一个数 求最大值
[抄题]: Given a non-negative integer, you could swap two digits at most once to get the maximum valued ...
- LeetCode Maximum Swap
原题链接在这里:https://leetcode.com/problems/maximum-swap/description/ 题目: Given a non-negative integer, yo ...
- [LeetCode] 670. Maximum Swap 最大置换
Given a non-negative integer, you could swap two digits at most once to get the maximum valued numbe ...
- 1095. Maximum Swap —— Weekly Challenge
题目限定输入是[0, 10^8],因而不用考虑负数或者越界情况,算是减小了难度. public class Solution { /** * @param num: a non-negative in ...
- 最大交换 Maximum Swap
2018-07-28 16:52:20 问题描述: 问题求解: 使用bucket数组来记录每个数最后出现的位置,然后从左向右遍历一遍即可. public int maximumSwap(int num ...
随机推荐
- flex-direction
[flex-direction] The flex-direction CSS property specifies how flex items are placed in the flex con ...
- 在centos xmanager工具环境下启动 xwindow
# 安装epel源 [root@linuxidc ~]# yum install -y epel-release # 安装lightdm和Xfce 1.安装 lightdm sudo yum inst ...
- 基于正则表达式用requests下载网页中的图片
在慕课网看了正则表达式和requests的课程后,为了加深学习记忆,决定简单记录. 实现步骤: 1.先打开你要下载的网页,查看源码找出图片位置 2.编写正则匹配图片url 3.保存图片到本地 图文步骤 ...
- AdminLTE 侧边栏收缩时触发的事件
点击此处,会触发 expanded.pushMenu 或 collapsed.pushMenu 事件 如果需要在事件触发时编写相关逻辑,可用如下方式 $("body").on(&q ...
- 比较perl+python
作者:iTech出处:http://itech.cnblogs.com/ http://hyperpolyglot.org/scripting perl (1987) python (1991) ...
- 论equals与==不同的重要性
首先借鉴一下CSDN前辈的总结: 在编程中,通常比较两个字符串是否相同的表达式是“==” ,但在 Java 中不能这么写.在 Java 中,如果要比较 a 字符串是否等于 b 字符串,需要这么写: i ...
- xadmin系列之django的url分发的方式
一.先介绍一下我们自己的urls中是如何进行路由分发的 一.一级路由 urlpatterns = [ url(r'^upload/', views.upload,name="upload&q ...
- bbs项目富文本编辑器实现上传文件到media目录
media目录是在project的settings中设置的,static目录是django自己使用的静态文件的上传目录,media目录是用户自定义上传文件的目录 # Django用户上传的文件都放在m ...
- Windows 64 位 mysql 5.7.20 安装教程
mysql 5.7以上版本包解压中没有data目录和my-default.ini和my.ini文件以及服务无法启动的解决办法以及修改初始密码的方法 mysql官网下载地址:https://dev.my ...
- Java_4 引用类型变量 Scanner与Random的使用
1.Scanner的使用 获得键盘输入的功能. 2.Random的使用 Random ran = new Random();//创建引用类型的变量 int number = ran.nextInt(1 ...