Arian Soleimanzadeh
  • Home
  • Blog
  • Podcasts
  • Videos
  • Contact
العربيةArabic
DeutschGerman
EnglishEnglish
فارسیPersian
한국어Korean
中文Chinese
Panel•Quick Contact

Languages

Choose your interface locale

ar

العربية

Arabic

de

Deutsch

German

en

English

English

fa

فارسی

Persian

ko

한국어

Korean

zh

中文

Chinese

Get Appointment

Drop a quick message — I’ll reply as soon as possible.

LinkedInFast response
Home/Articles/What Is a Palindrome? Two-Pointer Checking, TypeScript and Interview Patterns
AlgorithmsArticle

What Is a Palindrome? Two-Pointer Checking, TypeScript and Interview Patterns

A palindrome reads the same forward and backward. This guide explains palindrome checking with reversal, two pointers, normalization, numeric palindromes, complexity, TypeScript, and common interview variations.

August 19, 20268 min read8 Views
#Algorithms#Palindrome#Two Pointers#String Algorithms#TypeScript#Problem Solving#Computer Science

Arian Soleimanzadeh

Software Engineer & Researcher

Palindrome checking algorithm using two pointers moving from both ends of a string toward the center

Arian Soleimanzadeh

AI · Code · Product

Research + Engineering
On this page
Basic ideaMethod 1: Reverse the stringMethod 2: Two PointersTypeScript implementationWhy only half of the string?Ignoring spaces and punctuationChecking without creating a normalized copyNumeric palindromesRecursive solutionAlmost PalindromeWhy this problem mattersTwo Pointers as a general techniqueUnicode considerations in JavaScriptCase sensitivityCommon interview questionCommon mistakesUnclear normalization rulesUnnecessary extra memoryIncorrect loop conditionForgetting empty and single-character stringsReverse vs. Two PointersConclusion

A palindrome is a string, number, or sequence that reads the same forward and backward.

Examples include:

Code
1234
racecar
level
madam
1221

while:

Code
123
hello
algorithm
1234

are not palindromes.

Palindrome checking is a simple algorithmic problem, but it is particularly useful for learning Two Pointers, string traversal, recursion, normalization, and space optimization.


Basic idea

Consider:

Code
1
racecar

Reversing it gives:

Code
1
racecar

so it is a palindrome.

For:

Code
1
hello

we get:

Code
1
olleh

which is different.


Method 1: Reverse the string

The simplest solution creates a reversed copy and compares it with the original.

TypeScript
1234
function isPalindrome(value: string): boolean {
  const reversed = value.split("").reverse().join("");
  return value === reversed;
}

Its complexity is approximately:

Code
12
Time Complexity: O(n)
Space Complexity: O(n)

because a reversed representation must be created.


Method 2: Two Pointers

A more memory-efficient solution places one pointer at each end of the string.

Code
123
r a c e c a r
↑           ↑
L           R

Compare the two characters. If they match, move both pointers toward the center.

Code
12
left++
right--

If any pair differs, the string is not a palindrome.

Pseudocode:

Code
1234567891011
left = 0
right = length - 1

while left < right:
    if string[left] != string[right]:
        return false

    left++
    right--

return true

TypeScript implementation

TypeScript
123456789101112131415
function isPalindrome(value: string): boolean {
  let left = 0;
  let right = value.length - 1;

  while (left < right) {
    if (value[left] !== value[right]) {
      return false;
    }

    left++;
    right--;
  }

  return true;
}

Complexity:

Code
12
Time Complexity: O(n)
Space Complexity: O(1)

This is the standard interview-friendly solution.


Why only half of the string?

Every comparison checks two symmetric positions.

Once the pointers meet or cross, every relevant pair has already been tested.

The center character in an odd-length palindrome does not need a partner.


Ignoring spaces and punctuation

Real problems often use input such as:

Code
1
A man, a plan, a canal: Panama

After removing non-alphanumeric characters and converting to lowercase:

Code
1
amanaplanacanalpanama

it becomes a palindrome.

One solution is normalization:

TypeScript
12345
function normalize(value: string): string {
  return value
    .toLowerCase()
    .replace(/[^a-z0-9]/g, "");
}

Then apply the two-pointer algorithm.


Checking without creating a normalized copy

We can also skip punctuation while moving the pointers.

TypeScript
123456789101112131415161718192021222324252627282930
function isAlphaNumeric(char: string): boolean {
  return /[a-z0-9]/i.test(char);
}

function isPalindrome(value: string): boolean {
  let left = 0;
  let right = value.length - 1;

  while (left < right) {
    while (left < right && !isAlphaNumeric(value[left])) {
      left++;
    }

    while (left < right && !isAlphaNumeric(value[right])) {
      right--;
    }

    if (
      value[left].toLowerCase() !==
      value[right].toLowerCase()
    ) {
      return false;
    }

    left++;
    right--;
  }

  return true;
}

This retains the important two-pointer pattern without constructing another full string.


Numeric palindromes

Numbers can also be palindromes:

Code
123
121
1221
4554

The simplest solution converts the number to a string.

TypeScript
1234
function isNumberPalindrome(value: number): boolean {
  const text = String(value);
  return text === text.split("").reverse().join("");
}

Another solution reverses the digits mathematically.

TypeScript
12345678910111213141516
function isNumberPalindrome(value: number): boolean {
  if (value < 0) {
    return false;
  }

  const original = value;
  let reversed = 0;

  while (value > 0) {
    const digit = value % 10;
    reversed = reversed * 10 + digit;
    value = Math.floor(value / 10);
  }

  return original === reversed;
}

Negative integers are generally not treated as palindromes because the minus sign appears on only one side.


Recursive solution

Palindrome checking can also be expressed recursively.

TypeScript
12345678910111213141516171819
function isPalindromeRecursive(
  value: string,
  left = 0,
  right = value.length - 1
): boolean {
  if (left >= right) {
    return true;
  }

  if (value[left] !== value[right]) {
    return false;
  }

  return isPalindromeRecursive(
    value,
    left + 1,
    right - 1
  );
}

The time complexity remains O(n), but recursion consumes stack space, producing approximately O(n) additional space.

The iterative two-pointer version is therefore usually preferable.


Almost Palindrome

A common extension asks:

Can the string become a palindrome after deleting at most one character?

For example:

Code
1
abca

can become a palindrome by removing either b or c appropriately.

When the first mismatch appears, test two possibilities:

Code
12
skip left
skip right
TypeScript
1234567891011121314151617181920212223242526272829303132333435
function isRangePalindrome(
  value: string,
  left: number,
  right: number
): boolean {
  while (left < right) {
    if (value[left] !== value[right]) {
      return false;
    }

    left++;
    right--;
  }

  return true;
}

function validPalindrome(value: string): boolean {
  let left = 0;
  let right = value.length - 1;

  while (left < right) {
    if (value[left] !== value[right]) {
      return (
        isRangePalindrome(value, left + 1, right) ||
        isRangePalindrome(value, left, right - 1)
      );
    }

    left++;
    right--;
  }

  return true;
}

Why this problem matters

Palindrome checking is the foundation for more advanced problems including:

  • Longest Palindromic Substring
  • Palindromic Subsequence
  • Palindrome Partitioning
  • Minimum Insertions for Palindrome
  • Valid Palindrome
  • Almost Palindrome

The symmetric comparison pattern appears repeatedly in these problems.


Two Pointers as a general technique

The technique is much broader than palindrome problems.

Two Pointers also appears in problems such as:

  • Pair Sum in sorted arrays
  • Removing duplicates
  • Container With Most Water
  • Partitioning
  • Array merging
  • Several sequence-processing problems

Palindrome checking is one of the cleanest introductions to the technique.


Unicode considerations in JavaScript

JavaScript string indexing is based on UTF-16 code units, which means some Unicode symbols and emoji may occupy more than one unit.

For ASCII-focused interview problems this is normally irrelevant.

For Unicode-aware software, you may need a representation such as:

TypeScript
1
const chars = Array.from(value);

or more specialized Unicode processing depending on the requirements.


Case sensitivity

Whether:

Code
1
Level

is considered a palindrome depends on the rules.

Case-sensitive comparison says it is not, while normalizing to lowercase gives:

Code
1
level

which is a palindrome.

The normalization rules should therefore be part of the problem definition.


Common interview question

A typical problem says:

Determine whether a string is a palindrome while ignoring punctuation, spaces, and letter case.

Example:

Pseudocode
12345
Input:
A man, a plan, a canal: Panama

Output:
true

A strong solution uses:

Code
123
Two Pointers
+ Skip non-alphanumeric characters
+ Case-insensitive comparison

and achieves:

Code
12
Time: O(n)
Space: O(1)

without building a normalized copy.


Common mistakes

Unclear normalization rules

Always determine whether spaces, punctuation, case, and Unicode should matter.

Unnecessary extra memory

Reversing the string is valid, but an interviewer may specifically ask for constant extra space.

Incorrect loop condition

A common and clean condition is:

Code
1
left < right

Forgetting empty and single-character strings

Both are generally palindromes:

Code
12
""  → true
"a" → true

Reverse vs. Two Pointers

Reverse-based solution:

Code
12
Time:  O(n)
Space: O(n)

Two-pointer solution:

Code
12
Time:  O(n)
Space: O(1)

For algorithmic learning and technical interviews, Two Pointers is normally the more useful approach.


Conclusion

A palindrome reads identically from both directions.

The standard algorithmic solution uses two pointers:

Pseudocode
123456
left  → beginning
right → end

compare
↓
move inward

with:

Code
12
Time Complexity: O(n)
Space Complexity: O(1)

The value of this problem goes beyond recognizing words like racecar. It provides a clean introduction to symmetric reasoning, Two Pointers, normalization, edge cases, and memory-efficient string processing.

On this page
Basic ideaMethod 1: Reverse the stringMethod 2: Two PointersTypeScript implementationWhy only half of the string?Ignoring spaces and punctuationChecking without creating a normalized copyNumeric palindromesRecursive solutionAlmost PalindromeWhy this problem mattersTwo Pointers as a general techniqueUnicode considerations in JavaScriptCase sensitivityCommon interview questionCommon mistakesUnclear normalization rulesUnnecessary extra memoryIncorrect loop conditionForgetting empty and single-character stringsReverse vs. Two PointersConclusion

Article details

Publication metadata, reading time and live view information.

Published

August 19, 2026

Updated

August 23, 2026

Reading time

8 min read

Views

8

Author

Arian Soleimanzadeh

Previous article

Longest Common Substring Explained: Dynamic Programming, TypeScript and Real-World Uses

Next article

Regular Expression Matching Explained: Dynamic Programming, Memoization and TypeScript

Arian Soleimanzadeh

Personal portfolio focused on modern web engineering, UI systems, and practical AI products — clean code, clean design.

Quick Links

  • About
  • Blog
  • Contact

Contact

  • soleimanzadeh.a.work@gmail.com
  • soleimanzadeh.uni@gmail.com

Availability: Weekdays

Typically replies within 24h.

Newsletter

Get updates on posts, projects, and new releases.

© 2026 ariansoleimanzadeh.site — All rights reserved.

LinkedIn