670. 最大交换 : 简单模拟题
我报名参加金石计划一期挑战——瓜分10万奖池,这是我的第11篇文章,点击查看活动详情
题目描述
这是 LeetCode 上的 670. 最大交换 ,难度为 中等。
Tag : 「模拟」
给定一个非负整数,你至多可以交换一次数字中的任意两位。返回你能得到的最大值。
示例 1 :
输入: 2736
输出: 7236
解释: 交换数字2和数字7。
示例 2 :
输入: 9973
输出: 9973
解释: 不需要交换。
注意:
- 给定数字的范围是 [0,108][0, 10^8][0,108]
模拟
根据题意,我们应当将大的数放置在高位,而当有数值相同的多个大数时,我们应当选择低位的数字。
因此,我们可以先将 num
的每一位处理出来存放到数组 list
中,随后预处理一个与 list
等长的数组 idx
,带来代指 num
后缀中最大值对应的下标,即当 idx[i] = j
含义为在下标为 [0,i][0, i][0,i] 位中 num[j]num[j]num[j] 对应的数值最大。
同时由于我们需要遵循「当有数值相同的多个大数时,选择低位的数字」原则,我们应当出现采取严格大于才更新的方式来预处理 idx
。
最后则是从高位往低位遍历,找到第一个替换的位置进行交换,并重新拼凑回答案。
Java 代码:
class Solution {
public int maximumSwap(int num) {
List<Integer> list = new ArrayList<>();
while (num != 0) {
list.add(num % 10); num /= 10;
}
int n = list.size(), ans = 0;
int[] idx = new int[n];
for (int i = 0, j = 0; i < n; i++) {
if (list.get(i) > list.get(j)) j = i;
idx[i] = j;
}
for (int i = n - 1; i >= 0; i--) {
if (list.get(idx[i]) != list.get(i)) {
int c = list.get(idx[i]);
list.set(idx[i], list.get(i));
list.set(i, c);
break;
}
}
for (int i = n - 1; i >= 0; i--) ans = ans * 10 + list.get(i);
return ans;
}
}
TypeScript 代码:
function maximumSwap(num: number): number {
const list = new Array<number>()
while (num != 0) {
list.push(num % 10)
num = Math.floor(num / 10)
}
let n = list.length, ans = 0
const idx = new Array<number>()
for (let i = 0, j = 0; i < n; i++) {
if (list[i] > list[j]) j = i
idx.push(j)
}
for (let i = n - 1; i >= 0; i--) {
if (list[idx[i]] != list[i]) {
const c = list[idx[i]]
list[idx[i]] = list[i]
list[i] = c
break
}
}
for (let i = n - 1; i >= 0; i--) ans = ans * 10 + list[i];
return ans
};
- 时间复杂度:O(lognum)O(\log{num})O(lognum)
- 空间复杂度:O(lognum)O(\log{num})O(lognum)
最后
这是我们「刷穿 LeetCode」系列文章的第 No.670
篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:github.com/SharingSour… 。
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
更多更全更热门的「笔试/面试」相关资料可访问排版精美的 合集新基地 🎉🎉
转载自:https://juejin.cn/post/7142687592654307341