Question #405EasyDSAImportant

Write a function to check if a given string is a palindrome. Implement solutions for: (a) Case-sensitive, (b) Case-insensitive, (c) Ignoring spaces and special characters.

#algorithm#string#palindrome#dart#two-pointer

Answer

Overview

A palindrome is a string that reads the same forwards and backwards. Examples: "racecar", "madam", "A man a plan a canal Panama" (ignoring spaces/case). This fundamental string problem tests two-pointer techniques, string processing, and edge case handling.


Approach 1: Two-Pointer (Case-Sensitive)

Most efficient approach using two pointers from opposite ends.

dart
bool isPalindrome(String str) {
  if (str.isEmpty) return true;

  int left = 0;
  int right = str.length - 1;

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

  return true;
}

void main() {
  print(isPalindrome('racecar'));    // true
  print(isPalindrome('hello'));      // false
  print(isPalindrome('madam'));      // true
}

Time Complexity: O(n) - iterate through half the string Space Complexity: O(1) - only pointer variables


Approach 2: String Reversal

Reverse and compare - simpler but uses more memory.

dart
bool isPalindromeReverse(String str) {
  String reversed = str.split('').reversed.join('');
  return str == reversed;
}

void main() {
  print(isPalindromeReverse('racecar'));  // true
  print(isPalindromeReverse('hello'));    // false
}

Time Complexity: O(n) Space Complexity: O(n) - creates reversed string


Approach 3: Case-Insensitive

Convert to lowercase before checking.

dart
bool isPalindromeCaseInsensitive(String str) {
  str = str.toLowerCase();
  int left = 0, right = str.length - 1;

  while (left < right) {
    if (str[left++] != str[right--]) return false;
  }
  return true;
}

void main() {
  print(isPalindromeCaseInsensitive('Racecar'));  // true
  print(isPalindromeCaseInsensitive('MadAm'));    // true
}

Approach 4: Alphanumeric Only

Ignore spaces and special characters.

dart
bool isPalindromeAlphanumeric(String str) {
  String cleaned = str
      .toLowerCase()
      .replaceAll(RegExp(r'[^a-z0-9]'), '');

  int left = 0, right = cleaned.length - 1;

  while (left < right) {
    if (cleaned[left++] != cleaned[right--]) return false;
  }
  return true;
}

void main() {
  print(isPalindromeAlphanumeric(
    'A man, a plan, a canal: Panama'));  // true
  print(isPalindromeAlphanumeric('race a car'));  // false
}

Time: O(n) | Space: O(n)


Complete Solution

dart
class PalindromeChecker {
  static bool caseSensitive(String str) {
    int left = 0, right = str.length - 1;
    while (left < right) {
      if (str[left++] != str[right--]) return false;
    }
    return true;
  }

  static bool caseInsensitive(String str) {
    str = str.toLowerCase();
    int left = 0, right = str.length - 1;
    while (left < right) {
      if (str[left++] != str[right--]) return false;
    }
    return true;
  }

  static bool alphanumericOnly(String str) {
    str = str.toLowerCase().replaceAll(RegExp(r'[^a-z0-9]'), '');
    int left = 0, right = str.length - 1;
    while (left < right) {
      if (str[left++] != str[right--]) return false;
    }
    return true;
  }
}

Comparison

ApproachTimeSpaceBest For
Two-pointerO(n)O(1)Production
ReversalO(n)O(n)Prototypes
Case-insensitiveO(n)O(n)User input
AlphanumericO(n)O(n)NLP tasks

Edge Cases

dart
void testEdgeCases() {
  assert(isPalindrome('') == true);       // Empty
  assert(isPalindrome('a') == true);      // Single
  assert(isPalindrome('ab') == false);    // Different
  assert(isPalindrome('abba') == true);   // Even
  assert(isPalindrome('aba') == true);    // Odd
}

Best Practices

1. Handle Nulls

dart
bool isPalindromeSafe(String? str) {
  if (str == null || str.isEmpty) return true;
  // ... palindrome logic
}

2. Make Configurable

dart
bool isPalindrome(String str, {
  bool ignoreCase = false,
  bool alphanumericOnly = false,
}) {
  if (ignoreCase) str = str.toLowerCase();
  if (alphanumericOnly) str = str.replaceAll(RegExp(r'[^a-z0-9]'), '');

  int left = 0, right = str.length - 1;
  while (left < right) {
    if (str[left++] != str[right--]) return false;
  }
  return true;
}

Resources