Reverse Integer

Posted on

Problem

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;
};

Solution

  • 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;
}

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.

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;
    };
}

Leave a Reply

Your email address will not be published. Required fields are marked *