【算法-LeetCode】670. 最大交换(字符串;数组;解构赋值实现互换)

670. 最大交换 - 力扣(LeetCode)

文章起笔:2021年11月1日18:21:38

问题描述及示例

给定一个非负整数,你至多可以交换一次数字中的任意两位。返回你能得到的最大值。

示例 1 :
输入: 2736
输出: 7236
解释: 交换数字2和数字7。

示例 2 :
输入: 9973
输出: 9973
解释: 不需要交换。

注意:
给定数字的范围是 [0, 108]

我的题解

我的思路稍微有点绕,但是总体结构还是比较清晰的。

在这里插入图片描述

  1. 首先将数值类型的参数 num 转化为数字数组 numArr
  2. 再寻找 numArr 中出现的第一个升序转折点的下标值 start(见上图)。也就是说,在这个元素之前,数组元素的大小都是降序的,从这个元素开始出现了升序。
  3. start 开始往后寻找 numArr[start] 之后的 最靠后的最大元素 的下标值 maxNumIdx
  4. 然后从头开始寻找第一个小于 numArr[maxNumIdx] 的元素,将 numArr[maxNumIdx] 与其对换位置即为答案。
  5. 最后将调换过的数组重新还原为一个完整的数字。
/**
 * @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

参考:最大交换 - 最大交换 - 力扣(LeetCode)

【更新结束】

有关参考

更新:2021年11月1日18:33:08
参考:解构赋值 - JavaScript | MDN
参考:XOR swap algorithm - Wikipedia
参考:异或运算 XOR 教程 - 阮一峰的网络日志

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值