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]

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的更多相关文章

  1. LC 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 最大置换

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

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

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

  4. 670. Maximum Swap

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

  5. 670. Maximum Swap 允许交换一个数 求最大值

    [抄题]: Given a non-negative integer, you could swap two digits at most once to get the maximum valued ...

  6. LeetCode Maximum Swap

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

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

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

  8. 1095. Maximum Swap —— Weekly Challenge

    题目限定输入是[0, 10^8],因而不用考虑负数或者越界情况,算是减小了难度. public class Solution { /** * @param num: a non-negative in ...

  9. 最大交换 Maximum Swap

    2018-07-28 16:52:20 问题描述: 问题求解: 使用bucket数组来记录每个数最后出现的位置,然后从左向右遍历一遍即可. public int maximumSwap(int num ...

随机推荐

  1. Real Time Rendering 1

    [Real Time Rendering 1] 1.RTR是一本导论.官网:http://www.realtimerendering.com. 2.At around 6 fps, a sense o ...

  2. SQLMAP自动注入(三):参数介绍

    --delay延时扫描 --scope 从burpsuit日志中过滤日志内容,通过正则表达式筛选扫描目标,19开头,尾数为1.11.121.221的目标 --level=3 会检查user-agent ...

  3. Tomcat添加管理员role

       最近朋友问我怎么在Tomcat里面使用 admin 登录,一般情况下登录后是提示xxx的,经过百度后,好不容易才找到答案:    原来添加一个role为admin:<role rolena ...

  4. PHP 在 Mac 的安装之路

    半年前本以为有一些 Apache 和 PHP 的安装经验,今天在 Mac 上还是踩了很多坑. 坦诚地讲,这东西入门成本比 Node,Python 入门成本真的是大很多. Apache 的编译安装就是那 ...

  5. TOJ 4383 n % ( pow( p , 2) ) ===0

    传送门:http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=4383 描述 There is a ...

  6. http://ctf.bugku.com/challenges#Easy_Re

      今天做一道逆向题,开心,见证了自己汇编的用途.     首先看它是否加壳? 1.加壳检测   是vc编程的,没有加壳,可以愉快地分析了.   2.分析程序,找到flag.   首先运行一下子程序, ...

  7. jQuery之禁止Get请求缓存

    如果两次Get请求的URL完全一样,则IE浏览器会调用上次缓存的结果,不会发起新的Http请求. 解决办法:在URL最后面加上时间戳. jQuery全局设置禁止缓存 $.ajaxSetup({ cac ...

  8. 上海大都会赛 I Matrix Game(最大流)

    At the start of the matrix game, we have an N x M matrix. Each grid has some balls.The grid in (i,j) ...

  9. Java02-java语法基础(一)数据类型

    Java02-java语法基础(一)数据类型 一.语法基础 语句:以分号(;)结束 System.out.println(“Hello World !”); 语句块:用一组花括号({})括起来 { … ...

  10. linux minitools+minicom 安装及使用

    1,通过SSH将minitools的安装包传到ubuntu 文件下, 2,   解压minitools.tgz  (具体方法见上一篇) 3,命令安装minicom  :   apt-get insta ...