刷 整数反转 | 刷题打卡

179 阅读2分钟

一、题目描述:

原题地址

给你一个 32 位的有符号整数 x ,返回 x 中每位上的数字反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [−231,  231 − 1] ,就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)。

说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入:x = 123 输出:321 示例 2:

输入:x = -123 输出:-321 示例 3:

输入:x = 120 输出:21

二、思路分析:

我的第一感觉是用数组的reverse方法。。。,这法子空间和时间应该都是O(n) 但感觉类型来回折腾

对象提醒用用mod

得到每位数的逻辑是:

  • 用mod得到个位数
  • 用除运算得到个位数左边
  • 再将左边mod得到十位数
  • 以此类推,当左边是0的时候,表示数取完了

这题的思路:

  • 结果res初始值是0
  • mod得到个位数
  • 除法运算得到个位数左边
  • res 加上 个位数和res乘以10
  • 一直到最后,res也就算好了

这样的话空间应该是O(1),时间是O(n)

三、AC 代码:

reverse的土鳖方法:

const reverse = function (x) {
  let y = x;
  y = y < 0 ? y.toString().slice(1) : y.toString();
  y = y.split('').reverse().join('');
  if (x < 0) {
      y = -y;
  }
  const maxValue = Math.pow(2, 31);
  if (y < -maxValue || y > (maxValue - 1)) {
      return 0;
  }
  return y;
};

mod的方法:

const reverse = function (x) {
  let y = x;
  y < 0 && (y = -y);
  let res = 0;
  let right = 1;
  let left = y;
  while (left) {
    right = left % 10;
    left = Math.floor(left / 10);
    res = right + res * 10;
  }
  x<0 && (res = -res)
  const max = 2 ** 31;
  if (res > max - 1 || res < -max) {
    res = 0;
  }
  return res;
};
console.log(reverse(123456789));

四、总结:

拿到整数的每一位的时候,可以用mod和除法运算
得到一个整数的时候,用乘法和加法运算

以下两个是基本方法


// 123456 => [1,2,3,4,5,6]
function getSingleList(number) {
  const res = [];
  let left = number;
  let right;
  while (left) {
    right = left % 10;
    left = Math.floor(left / 10);
    res.unshift(right);
  }
  return res;
}
console.log(getSingleList(123456));

// [1,2,3,4,5,6] => 123456
// 每多一位,新的位就是个位数 之前的就变成十位数
function getNumber(singleList) {
  const acc = 0;
  const fn = (acc, cur) => (acc = cur + acc * 10);
  return singleList.reduceRight(fn, acc);
}
console.log(getNumber([1,2,3,4,5,6]));