41. Write a PHP function to determine whether a string is a palindrome.
Ignore letter case and define how spaces and punctuation are handled. Return a boolean and explain edge cases and time and space complexity.
I would first remove spaces, punctuation, and other non-alphanumeric ASCII characters, then convert the remaining text to lowercase. I would use two pointers, with one at the start and one at the end. I compare each mirrored pair. If any pair differs, I return false immediately. If the pointers meet or cross, every required pair matched, so I return true. Normalization and comparison take O(n) time. The normalized copy uses O(n) auxiliary space.
See the Code while reading this explanation.
The function receives a string and returns either true or false. Letter case must not affect the result. Spaces and punctuation must also be ignored. I first create a cleaned lowercase string that contains only ASCII letters and digits. I then compare characters from the two ends and move toward the center. This method fits the problem because a palindrome has equal characters in every mirrored position. It can also stop as soon as one mismatched pair proves that the string is not a palindrome.
- Should digits remain in the normalized string?
- Should an empty normalized string be treated as a palindrome?
- Is ASCII-only handling acceptable, or must the function support full Unicode text?
The input is one string. The function returns a boolean. It returns true when the normalized string reads the same from left to right and right to left. It returns false when any mirrored character pair differs.
The shown solution ignores spaces and punctuation by removing every character except ASCII letters and digits. It ignores letter case by converting the cleaned string to lowercase.
I use two pointers. The left pointer starts at the first character. The right pointer starts at the last character. They compare mirrored positions and move inward after every match.
The central invariant is that every character pair outside the current pointer range has already matched. A mismatch immediately proves that the string is not a palindrome.
The example input is "Race a car!".
After removing spaces and punctuation and converting the text to lowercase, the normalized string is "raceacar".
Its length is 8. The left pointer starts at index 0. The right pointer starts at index 7.
The indexed characters are: 0:r, 1:a, 2:c, 3:e, 4:a, 5:c, 6:a, 7:r.
Step 1 starts with left = 0 and right = 7. The characters are r and r. The condition r === r is true, so left becomes 1 and right becomes 6.
Step 2 compares indices 1 and 6. The characters are a and a. They match, so left becomes 2 and right becomes 5.
Step 3 compares indices 2 and 5. The characters are c and c. They match, so left becomes 3 and right becomes 4.
Step 4 compares indices 3 and 4. The characters are e and a. The condition e !== a is true, so the function returns false immediately. Processing stops at this point.
The first three mirrored pairs match. The fourth pair does not match. A palindrome requires every mirrored pair to match. Therefore, the normalized string "raceacar" is not a palindrome, and false is the correct result.
If no mismatch were found and the pointers met or crossed, the invariant would show that every mirrored pair had matched. The function could then safely return true.
preg_replace removes every character except ASCII letters and digits. The null-coalescing operator provides an empty string if preg_replace returns null. strtolower converts the cleaned result to lowercase.
The variables $left and $right store the current pointer positions. The while loop continues while $left is less than $right. A mismatched pair returns false immediately. A matching pair moves both pointers toward the center. If the loop finishes, the function returns true.
Normalization takes O(n) time. The two-pointer scan takes O(n) time in the worst case. The total time remains O(n). The normalized string requires O(n) auxiliary space.
An empty string returns true after normalization. A string containing only punctuation also returns true because its normalized form is empty. Mixed case is handled by strtolower. A numeric palindrome such as "1221" returns true. A short mismatch such as "ab" returns false. The shown implementation is ASCII-focused and does not provide complete Unicode handling.
The key insight is that a palindrome must have equal characters in mirrored positions. The solution first normalizes the input by removing every character except ASCII letters and digits, then converting the result to lowercase. It places one pointer at each end of the normalized string. Matching characters allow both pointers to move inward. A mismatch returns false immediately. The invariant is that every pair outside the current pointer range has already matched. If the pointers meet or cross without a mismatch, all mirrored pairs match, so the function returns true.
<?php
/**
* Return true when the normalized string is a palindrome.
*
* Rules used by this solution:
* - Ignore ASCII letter case.
* - Remove spaces, punctuation, and other non-alphanumeric ASCII characters.
* - Keep ASCII digits.
*/
function isPalindrome(string $text): bool
{
// Step 1: Remove every character except ASCII letters and digits.
// Step 2: Convert the cleaned string to lowercase.
$normalized = strtolower(
preg_replace('/[^a-z0-9]/i', '', $text) ?? ''
);
// Step 3: Place one pointer at each end of the normalized string.
$left = 0;
$right = strlen($normalized) - 1;
// Step 4: Compare mirrored characters until the pointers meet or cross.
while ($left < $right) {
// Step 5: A mismatch proves that the string is not a palindrome.
if ($normalized[$left] !== $normalized[$right]) {
return false;
}
// Step 6: The pair matched, so move both pointers inward.
$left++;
$right--;
}
// Every required mirrored pair matched.
return true;
}
// Example from the approved diagram.
$input = "Race a car!";
$result = isPalindrome($input);
var_dump($result); // bool(false)Let n be the length of the original input string. Normalizing the input takes O(n) time because the characters must be examined. The two-pointer loop also takes O(n) time in the worst case, although it may stop early after a mismatch. Because these two operations happen one after another, the total time complexity is O(n). The function stores a normalized copy whose size can grow with the input, so the auxiliary space complexity is O(n).
This normalization and two-pointer pattern is useful when software must compare text while ignoring formatting differences. Examples include simplified phrase validation, normalized identifier checks, text-cleaning utilities, and interview problems that compare values from opposite ends of a sequence. The same two-pointer idea also appears in sorted-array searches and shrinking-range problems.
This problem tests whether a candidate can clarify text-processing rules, recognize the two-pointer pattern, and maintain a simple correctness invariant. It also checks early-return reasoning, pointer movement, PHP string handling, and accurate complexity analysis. The interviewer may also look for awareness of edge cases such as empty input, punctuation-only input, mixed case, digits, and the difference between ASCII-focused processing and full Unicode support.
A common mistake is comparing the original string without first removing spaces and punctuation. Another is forgetting to convert the text to lowercase. Candidates may move only one pointer after a match, use an incorrect loop condition, or continue processing after a mismatch instead of returning false immediately. It is also incorrect to claim O(1) auxiliary space because this implementation creates a normalized copy. Finally, the regular expression and strtolower are ASCII-focused, so the code should not be described as fully Unicode-safe.
Before coding, state the normalization rule and the invariant: every pair outside the current pointer range has already matched. Then trace the exact pairs r/r, a/a, c/c, and e/a. This makes the early false return easy to explain and proves that the code matches the example.










