4
\$\begingroup\$

The task is taken from leetcode

Given a 32-bit signed integer, reverse digits of an integer.

Example 1:

Input: 123

Output: 321

Example 2:

Input: -123

Output: -321

Example 3:

Input: 120

Output: 21

Note:

Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−2^31, 2^31 − 1]. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.

My solution

/**
 * @param {number} x
 * @return {number}
 */
const reverse = x => {
  if (x === undefined || x === null) { return; }
  if (x < 10 && x >= 0) { return x; }

  const num = [];
  const dissectNum = n => {
    if (n <= 0) { return; }
    const y = n % 10;
    num.push(y);
    return dissectNum(Math.floor(n / 10));
  };
  dissectNum(Math.abs(x));
  let tmp = 0;
  const maxPow = num.length - 1;
  for (let i = 0; i < num.length; i++) {
    tmp += num[i] * Math.pow(10, maxPow - i);
  }
  const result = (x < 0 ? -1 : 1 ) * tmp;
  return result > Math.pow(-2, 31) && result < (Math.pow(2, 31) - 1)
    ? result
    : 0;
};
\$\endgroup\$
7
\$\begingroup\$
  • The question states that the input is a number 32 signed int so checking for undefined or null is a waste of time.

The solution is a little long. Some of it due to not being familiar with some old school short cuts.

-JavaScript numbers are doubles but when you use bitwise operations on them they are converted to 32 bit signed integers. This gives you a very easy way to check if the result has overflowed.

const signedInt = value => (value | 0)  === value; // returns true if int32
  • A 32 bit int can store 9 full decimal digits, with an extra digit 1 or 2, and a sign. you dont need to use an array to hold the reversed digits you can store them in the reversed number as you go.

  • JavaScript can handle hex 0x10 === 16, decimal 10 === 10, octal 010 === 8 and binary 0b10 === 2 (oh and BIG ints 10n === 10) Hex makes realy easy to remember the lowest and highest int for a given size.

    Not that you need them to solve the problem, just some handy info.

Some common ways of writing min max 32Ints

 const MIN = Math.pow(-2, 31), MAX = Math.pow(2, 31) - 1;


// negative
-0x80000000 === MIN;      // true
(0x80000000 | 0) === MIN; // true. Coerce from double to int32 
1 << 31 === MIN;          // true. Shift 1 to the highest (MSB) bit for negative

//positive
0x7FFFFFFF === MAX; // true
~(1 << 31) === MAX; // true  Flips bits of min int32

Rewrite

With that info you can rewrite the solution as

function reverseDigits(int) {
    var res = 0, val = Math.abs(int);
    while (val > 0) {
        res = res * 10 + (val % 10);
        val = val / 10 | 0;
    }
    res *= Math.sign(int);
    return (res | 0) === res ? res : 0;
}
\$\endgroup\$
4
\$\begingroup\$

I'd just use string manipulation on this, with a simple conditional for the edge cases.

var reverse = n => {
  const s = parseInt([..."" + n].reverse().join(""));
  return s >= 2 ** 31 ? 0 : Math.sign(n) * s;
};

The approach is to stringify the number, arrayify the string, reverse it, re-join the array into a string and finally parse the reversed string to an integer. parseInt called on a string such as "546-" will strip the trailing -. Then, handle overflow and positive/negative conditions and return the result.

In short, avoid overcomplication and take advantage of high-level language features when possible.

\$\endgroup\$
1
\$\begingroup\$

Both answers require you to use Math.sign. To avoid compatibility issues with some browsers, you could add the following script in your solution.

if (Math.sign === undefined) {
    Math.sign = function ( x ) {
        return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : +x;
    };
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.