The Palindrome Number Problem: Strings vs. Maths in JavaScript

Abstract image used to represent Palindrome Number: Strings vs. Maths in JavaScript
Image by Jakob Owens.

A palindrome number can be checked by converting it to text or by reversing its digits arithmetically. Related exercises such as the validpalindrome problem and the longestpalindromicsubstring problem use some of the same reasoning, but a number also gives us an arithmetic route. Both approaches can be correct. The useful comparison is clarity against the constraints, including negative values, trailing zeroes, and whether allocating a string is intentionally offlimits.

If you want to read the original problem first, you can find Palindrome Number on LeetCode. But how do we determine if a number is a palindrome? The answer lies in two main approaches: string manipulation and mathematical operations.


Understanding the Problem

Given an integer x in the range -2147483648 <= x <= 2147483647, determine whether it is a palindrome. An integer is a palindrome when it reads the same backwards as forwards. For instance, 121 is a palindrome, whilst -121 is not: it reads 121- backwards.

Converting the number to a string is allowed in the original problem. Solving it without that conversion is the optional followup, which gives us a useful reason to explore the arithmetic version too.

Constraints

  • The input is a signed 32bit integer. The optional followup asks for a solution without converting it to a string.
  • Negative numbers are nonpalindromic: -121 is not the same as 121-.

This problem serves as an excellent exercise in understanding number manipulation, string operations, and the nuances between different algorithmic solutions. As we delve deeper, I'll describe both stringbased and mathematical methods, evaluating the pros and cons of each.


Setting the Scene

When we see a number (like 1234321), it is fairly evident to our human eyes that it reads the same backwards. However, for a computer, it's not as straightforward.

There are two main approaches that can be considered in solving this:

  • Convert the number to a string and check for equality.
  • Use mathematical operations to reverse the number and compare.

The String Method

Personally, this is the method I reached for first. It is quite intuitive to convert the number to a string and then check if it is equal when read forwards and backwards.

For example:

const isPalindromeString = (num: number): boolean => {
  const str = num.toString();
  return str === str.split('').reverse().join('');
};

This version allocates a string and an array of its digits. Within the challenge's bounds, there are at most ten digits to inspect. For a generalpurpose version, JavaScript's Number type only represents every integer exactly between -(2 ** 53 - 1) and 2 ** 53 - 1. Larger integer inputs need an explicit representation such as a string or BigInt, and an implementation written for it.


The Mathematical Method

Instead of relying on string manipulations, we can reverse the number mathematically and then check if the original and reversed numbers are the same. Like this:

const isPalindromeMath = (num: number): boolean => {
  if (num < 0 || (num % 10 === 0 && num !== 0)) return false;

  let reversed = 0;
  while (num > reversed) {
    reversed = reversed * 10 + (num % 10);
    num = Math.floor(num / 10);
  }

  return num === reversed || num === Math.floor(reversed / 10);
};

If you have read other articles on my blog, you might recognise that this is very similar to another integer problem: reversing numbers coincidentally also with a stringbased and a mathsbased solution.

How It Works

  • Negative numbers are not palindromic by definition in this context.
  • We reverse half of the number to avoid overflow issues.
  • If the length of the number is odd, the middle digit doesn't matter in palindromicity, so we floordivide the reversed number by 10.

Why Maths Over String?

Although the stringbased solution is straightforward, the mathematical solution offers several advantages:

  1. Time: Both approaches inspect the digits. Which is faster depends on the engine and inputs; measure if it matters to the application.
  2. Memory: The arithmetic version keeps a few numeric variables and avoids the string and array allocations.
  3. Versatility:

    The mathematical solution works in environments that may not support string operations conveniently although this seems unlikely in JavaScript!

Final Thoughts

Both versions solve this bounded problem. I would start with the one the next person maintaining the code can follow, unless the nostring followup or measured allocation costs give us a reason to choose the arithmetic version.

Converting the number to a string produces the clearest comparison. Reversing half of the number avoids the string allocation and demonstrates the arithmetic pattern, but it needs explicit handling for negatives and trailing zeroes. Choose the version whose tradeoff matches the reason you are solving the problem.


Untangling a delivery problem?

Send the symptoms, constraints, and affected routes. I'll help identify whether the issue sits in the application, platform, content model, deployment path, or search surface.