题目
分析
这题有两种思路,
第一种
是平铺直叙的方式,
按照题目意思直接分布写就好,大致是如下步骤:
1 先检查x是否为0或者超出范围,如果是,则返回0
2 数字末尾为0的,先把0去掉
3 用数组反转的方法,把数字反转过来
4 把x的值先当作正数处理,在返回最终结果时,如果x为负值,就在结果中加上负号即可
5 检查反转后的结果是否超出范围,如果是,则返回0
第二种
就有一定的技巧,对性能提升很大,难度也有点提升
大致是这样的步骤:
1 先检查x是否为0或者超出范围,如果是,则返回0
2 把x转成正数进行处理,如果x是负数,在最终返回结果时,加个负号即可
3 算法核心
先假定一个最终结果,比如result,设为0
对x取模,拿到x的最后一位数字,然后把这个数字交给result,作为result的首位数字
此时对result做检查,看result是否超出了范围。
如果超出,则直接返回0,不再执行下去了。如果没超出范围,继续执行。
然后把原来x去掉最后一位数字后的数字,再作为x
比如数字1230
对1230取模,获取到最后一位数字为0
把0交给result ,result = result * 10 + 0
此时result的结果还是0,在这里可以知道,末尾为0的数字不需要单独处理了
数字x去掉最后一位数字0,变成了123, 这时候让x = 123 ,继续处理
对x取模,得到数字3,把3再交给result,
result = result * 10 + 3 , 得到当前的result是数字3
对result做检查,发现3没有超出范围,继续执行。
数字x去掉了最后一位数字3,现在x已经变成了12
重复上述步骤,可以得到数字123
4 返回结果。 如果x是正数,就直接返回result 。如果x是负数,就返回-result
解题
通过上述分析,可以得出两种解题结果。
第一种:
/**
* @param {number} x
* @return {number}
*/
var reverse = function(x) {
if(x === 0 || x < -Math.pow(2, 31) || x > (Math.pow(2, 31) - 1)) return 0
// 去除末尾的0
function switchX(x) {
if (x % 10 === 0) {
x /= 10
return switchX(x)
}
return x
}
let _x = Math.abs(x)
let _x_ = switchX(_x)
let __x = parseInt(Array.from(_x_.toString()).reverse().join(''))
if(-__x < -Math.pow(2, 31) || __x > (Math.pow(2, 31) - 1)) {
return 0
}
return x > 0 ? __x : -__x
};
第二种:
/**
* @param {number} x
* @return {number}
*/
var reverse = function(x) {
if(x === 0 || x < -Math.pow(2, 31) || x > (Math.pow(2, 31) - 1)) return 0
let a = Math.abs(x)
let result = 0
while(a != 0) {
_x = a % 10
result = result * 10 + _x
if (result > (Math.pow(2, 31) - 1) || -result < -Math.pow(2, 31)) {
return 0
}
a = (a - _x) / 10
}
return x > 0 ? result : -result
};
提交
第一种解题的提交结果:
第二种解题的提交结果:
虽然表面上看执行用时只相差了8ms,但是实际上第一种方法在内存消耗上只击败了10%几的用户。。
所以,第二种方法明显更好。