670. 最大交换 - 力扣(LeetCode)
文章起笔:2021年11月1日18:21:38
问题描述及示例
给定一个非负整数,你至多可以交换一次数字中的任意两位。返回你能得到的最大值。
示例 1 :
输入: 2736
输出: 7236
解释: 交换数字2和数字7。
示例 2 :
输入: 9973
输出: 9973
解释: 不需要交换。
注意:
给定数字的范围是 [0, 108]
我的题解
我的思路稍微有点绕,但是总体结构还是比较清晰的。
- 首先将数值类型的参数
num
转化为数字数组numArr
。 - 再寻找
numArr
中出现的第一个升序转折点的下标值start
(见上图)。也就是说,在这个元素之前,数组元素的大小都是降序的,从这个元素开始出现了升序。 - 从
start
开始往后寻找numArr[start]
之后的 最靠后的最大元素 的下标值maxNumIdx
。 - 然后从头开始寻找第一个小于
numArr[maxNumIdx]
的元素,将numArr[maxNumIdx]
与其对换位置即为答案。 - 最后将调换过的数组重新还原为一个完整的数字。
/**
* @param {number} num
* @return {number}
*/
var maximumSwap = function(num) {
// 将 num 转为数字数组,这里对应上面第1步
let numArr = num.toString().split('').map(Number);
// 开始寻找第一个升序转折点的下标值start,对应上面第2步
let start = 0;
while(start < numArr.length - 1) {
if(numArr[start] < numArr[start+1]) {
break;
}
start++;
}
// 寻找最靠后的最大元素的下标值 maxNumIdx,对应上面第3步
// 注意,这里是从 start 开始寻找最大值
let maxNumIdx = start;
for(let i = start; i < numArr.length; i++) {
maxNumIdx = numArr[maxNumIdx] <= numArr[i] ? i : maxNumIdx;
}
// 从头开始寻找第一个小于 numArr[maxNumIdx] 的元素,将其与 numArr[maxNumIdx]交换,
// 对应上面第4步,注意这里利用了解构赋值来完成互换操作,其他实现方式可看下方有关参考
for(let i = 0; i <= start; i++) {
if(numArr[i] < numArr[maxNumIdx]) {
[numArr[i], numArr[maxNumIdx]] = [numArr[maxNumIdx], numArr[i]];
break;
}
}
// 最后将调换了一次位置的numArr重新组合为一个数字作为返回值返回
return Number(numArr.join(''));
};
提交记录
执行结果:通过
111 / 111 个通过测试用例
执行用时:72 ms, 在所有 JavaScript 提交中击败了52.38%的用户
内存消耗:37.9 MB, 在所有 JavaScript 提交中击败了48.68%的用户
时间:2021/11/01 18:24
上面的互换操作用到了解构赋值,可以参考下方描述:
以上描述来自MDN的相关文档 解构赋值 - JavaScript | MDN
当然,除了上面那种方法,利用异或操作也可以实现交换两个变量的值的操作。
以上描述来自阮一峰的相关个人博客 异或运算 XOR 教程 - 阮一峰的网络日志
官方题解
更新:2021年7月29日18:43:21
因为我考虑到著作权归属问题,所以【官方题解】部分我不再粘贴具体的代码了,可到下方的链接中查看。
【更新结束】
更新:2021年11月1日18:26:36
【更新结束】
有关参考
更新:2021年11月1日18:33:08
参考:解构赋值 - JavaScript | MDN
参考:XOR swap algorithm - Wikipedia
参考:异或运算 XOR 教程 - 阮一峰的网络日志