Bird
Raised Fist0
DSA Cprogramming

Valid Palindrome Two Pointer in DSA C

Choose your learning style10 modes available
Mental Model
Use two pointers starting from both ends of the string and move towards the center, comparing characters to check if the string reads the same forwards and backwards.
Analogy: Imagine two friends starting at opposite ends of a hallway, walking towards each other while checking if the tiles under their feet match. If all matching tiles are the same, the hallway is symmetrical.
s = "racecar"

Indices: 0 1 2 3 4 5 6
String: r a c e c a r
Pointers:
left ↑                 right ↑
Dry Run Walkthrough
Input: string: "racecar"
Goal: Check if the string is a palindrome by comparing characters from both ends moving inward.
Step 1: Compare characters at left=0 and right=6 ('r' and 'r')
r [left->r] a c e c a [right->r]
Pointers move inward: left=1, right=5
Why: Characters match, so continue checking inner characters
Step 2: Compare characters at left=1 and right=5 ('a' and 'a')
r a [left->a] c e c [right->a] r
Pointers move inward: left=2, right=4
Why: Characters match, continue checking
Step 3: Compare characters at left=2 and right=4 ('c' and 'c')
r a c [left->c] e [right->c] a r
Pointers move inward: left=3, right=3
Why: Characters match, continue checking
Step 4: Pointers meet at left=3 and right=3 ('e')
r a c e [left->e,right->e] c a r
Pointers crossed or met, all checks passed
Why: Middle character reached, string is palindrome
Result:
r a c e c a r
Palindrome: true
Annotated Code
DSA C
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#include <string.h>

bool isPalindrome(char *s) {
    int left = 0;
    int right = strlen(s) - 1;

    while (left < right) {
        // Skip non-alphanumeric on left
        while (left < right && !isalnum(s[left])) {
            left++;
        }
        // Skip non-alphanumeric on right
        while (left < right && !isalnum(s[right])) {
            right--;
        }
        // Compare characters case-insensitively
        if (tolower(s[left]) != tolower(s[right])) {
            return false;
        }
        left++;
        right--;
    }
    return true;
}

int main() {
    char s[] = "racecar";
    if (isPalindrome(s)) {
        printf("%s\nPalindrome: true\n", s);
    } else {
        printf("%s\nPalindrome: false\n", s);
    }
    return 0;
}
while (left < right) {
loop until pointers meet or cross
while (left < right && !isalnum(s[left])) { left++; }
skip non-alphanumeric characters from left
while (left < right && !isalnum(s[right])) { right--; }
skip non-alphanumeric characters from right
if (tolower(s[left]) != tolower(s[right])) { return false; }
compare characters ignoring case, return false if mismatch
left++; right--;
move pointers inward to check next characters
OutputSuccess
racecar Palindrome: true
Complexity Analysis
Time: O(n) because we scan the string once with two pointers moving inward
Space: O(1) because we use only a few variables regardless of input size
vs Alternative: Compared to reversing the string and comparing, this uses less space and can stop early on mismatch
Edge Cases
empty string
returns true because empty string reads the same forwards and backwards
DSA C
while (left < right) {
string with only non-alphanumeric characters
skips all characters and returns true
DSA C
while (left < right && !isalnum(s[left])) { left++; }
string with mixed case and punctuation, e.g. "A man, a plan, a canal: Panama"
ignores case and non-alphanumeric, returns true
DSA C
if (tolower(s[left]) != tolower(s[right])) { return false; }
When to Use This Pattern
When you need to check if a string reads the same forwards and backwards ignoring cases and symbols, use the two pointer pattern to compare characters from both ends efficiently.
Common Mistakes
Mistake: Not skipping non-alphanumeric characters causing wrong mismatch
Fix: Add loops to skip non-alphanumeric characters before comparing
Mistake: Comparing characters without ignoring case
Fix: Use tolower() or toupper() to compare characters case-insensitively
Mistake: Moving pointers incorrectly causing infinite loop or missed checks
Fix: Increment left and decrement right only after successful comparison
Summary
Checks if a string is a palindrome by comparing characters from both ends moving inward.
Use when you want to verify palindrome ignoring case and non-alphanumeric characters efficiently.
The key insight is to use two pointers moving inward and skip irrelevant characters before comparing.

Practice

(1/5)
1. What is the main idea behind the two-pointer technique to check if a string is a palindrome?
easy
A. Count the frequency of each character and check if all are even
B. Sort the string and check if it matches the original
C. Reverse the string and compare with the original
D. Use two pointers starting from both ends and move towards the center comparing characters

Solution

  1. Step 1: Understand two-pointer setup

    Two pointers start at the beginning and end of the string to compare characters.
  2. Step 2: Move pointers inward while characters match

    If characters at both pointers are equal, move pointers closer until they meet or cross.
  3. Final Answer:

    Use two pointers starting from both ends and move towards the center comparing characters -> Option D
  4. Quick Check:

    Two-pointer palindrome check = Use two pointers starting from both ends and move towards the center comparing characters [OK]
Hint: Compare characters from ends moving inward [OK]
Common Mistakes:
  • Trying to sort the string which changes order
  • Only checking half the string without pointers
  • Ignoring non-alphanumeric characters if required
2. Which of the following C code snippets correctly initializes two pointers for palindrome checking on a string s?
easy
A. int left = 0, right = strlen(s) - 1;
B. int left = 1, right = strlen(s);
C. int left = 0, right = strlen(s);
D. int left = 1, right = strlen(s) - 1;

Solution

  1. Step 1: Understand string indexing in C

    Strings are zero-indexed, so first character is at 0 and last at length-1.
  2. Step 2: Correct pointer initialization

    Left pointer starts at 0, right pointer at strlen(s)-1 to cover full string.
  3. Final Answer:

    int left = 0, right = strlen(s) - 1; -> Option A
  4. Quick Check:

    Indexing starts at 0, last index = length-1 [OK]
Hint: Start left at 0 and right at length minus one [OK]
Common Mistakes:
  • Setting right pointer to strlen(s) which is out of bounds
  • Starting left pointer at 1 skipping first character
  • Using wrong indices causing runtime errors
3. What will be the output of the following C code snippet?
char s[] = "racecar";
int left = 0, right = strlen(s) - 1;
int isPalindrome = 1;
while (left < right) {
    if (s[left] != s[right]) {
        isPalindrome = 0;
        break;
    }
    left++;
    right--;
}
printf("%d", isPalindrome);
medium
A. 0
B. 1
C. 7
D. Compilation error

Solution

  1. Step 1: Trace pointer comparisons on "racecar"

    Characters at left and right match: 'r'=='r', 'a'=='a', 'c'=='c', 'e'=='e'.
  2. Step 2: Loop completes without mismatch

    No mismatch found, so isPalindrome remains 1 and prints 1.
  3. Final Answer:

    1 -> Option B
  4. Quick Check:

    "racecar" is palindrome = 1 [OK]
Hint: Check matching pairs from ends; no mismatch means palindrome [OK]
Common Mistakes:
  • Assuming output is string instead of integer
  • Confusing index bounds causing wrong comparisons
  • Forgetting to break loop on mismatch
4. Identify the bug in the following C code that checks if a string s is a palindrome using two pointers:
int left = 0, right = strlen(s);
while (left <= right) {
    if (s[left] != s[right]) {
        return 0;
    }
    left++;
    right--;
}
return 1;
medium
A. Both A and B are bugs
B. Loop condition should be left < right, not left <= right
C. Right pointer should be initialized to strlen(s) - 1
D. No bug, code is correct

Solution

  1. Step 1: Check right pointer initialization

    Right pointer set to strlen(s) is out of bounds; should be strlen(s) - 1.
  2. Step 2: Check loop condition

    Loop should run while left < right to avoid comparing same middle character twice.
  3. Final Answer:

    Both A and B are bugs -> Option A
  4. Quick Check:

    Right pointer and loop condition both incorrect = Both A and B are bugs [OK]
Hint: Right pointer = length-1 and loop: left < right [OK]
Common Mistakes:
  • Using strlen(s) as right pointer causing out-of-bounds access
  • Using <= in loop causing unnecessary comparison
  • Ignoring off-by-one errors
5. Given a string s that may contain uppercase letters, lowercase letters, and non-alphanumeric characters, which approach correctly checks if s is a palindrome ignoring cases and non-alphanumeric characters using two pointers?
hard
A. Count frequency of alphanumeric characters and check if all counts are even
B. Convert entire string to lowercase, remove non-alphanumeric chars, then compare with reversed string
C. Use two pointers from ends, skip non-alphanumeric chars, compare lowercase characters
D. Use two pointers but compare characters directly without skipping or case conversion

Solution

  1. Step 1: Use two pointers and skip non-alphanumeric characters

    Move left and right pointers inward, skipping characters that are not letters or digits.
  2. Step 2: Compare characters in lowercase form

    Convert characters to lowercase before comparing to ignore case differences.
  3. Final Answer:

    Use two pointers from ends, skip non-alphanumeric chars, compare lowercase characters -> Option C
  4. Quick Check:

    Two-pointer with skip and lowercase = Use two pointers from ends, skip non-alphanumeric chars, compare lowercase characters [OK]
Hint: Skip non-alphanumeric and compare lowercase chars with two pointers [OK]
Common Mistakes:
  • Comparing characters without skipping non-alphanumeric
  • Not converting characters to lowercase before comparison
  • Using frequency count which doesn't check order
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard