How to check if a string is a palindrome in C#

Key takeaways:

  • Using two pointers to traverse the string is faster and more memory-efficient, especially for large inputs.

  • This exercise strengthens core string manipulation techniques, like filtering, traversing, and logical validation.

  • Recursive palindrome checks are concise and intuitive for small strings, offering a clear view of the problem's structure.

  • Handling inputs like empty strings and single characters ensures your solution is comprehensive and reliable.

Understanding palindromes

A palindrome is a word, phrase, or sequence of characters that reads the same backward as forward, ignoring case, spaces, and punctuation. Examples include words like “radar,” “level,” “civic,” “deified,” and “noon,” which demonstrate symmetry by appearing identical when read in either direction. Numeric palindromes like “12321” and “45654” also maintain their integrity when their digits are reversed. Checking if a string is a palindrome is a common problem in programming, and C# provides efficient tools to solve it. In this Answer, we’ll explore step-by-step methods to check for palindromes in C#.

Example of palindrome
Example of palindrome

Approaches to check a palindrome in C#

When determining whether a string is a palindrome in C#, there are multiple methods to consider. In this discussion, we will focus on two core strategies: the iterative approach and the recursive approach.

The iterative approach uses two pointers, one starting at the beginning of the string and the other at the end. These pointers move toward the center, comparing characters at each step. If all corresponding characters match, the string is a palindrome.

In contrast, the recursive approach relies on a function that compares characters at the opposite ends of the string, then moves inward by recursively calling itself to validate the remaining substring. Both techniques are effective and provide unique perspectives on evaluating palindromes in C#.

Iterative approach

The iterative approach uses a straightforward loop to evaluate whether a string is a palindrome. It employs two pointers: one starting at the beginning of the string and the other at the end. The pointers move toward the center of the string, comparing characters at each step. If all characters match, the string is a palindrome. If any mismatch occurs, the process terminates early, confirming that the string is not a palindrome.

Steps

  1. Initialize pointers: Define two pointers: left starts at the beginning of the string (left = 0), and right starts at the end of the string (right = str.Length - 1).

  2. Compare characters: Check if the characters at the positions str[left] and str[right] are equal.

  3. Move pointers: If the characters match, increment the left pointer by 1 (left++) to move it forward and decrement the right pointer by 1 (right--) to move it backward.

  4. Mismatch check: If the characters at any point do not match, return false, as the string is not a palindrome.

  5. Repeat comparison: Continue steps 2–4 until the left pointer meets or crosses the right pointer (left >= right).

  6. Completion: If the loop completes without encountering any mismatches, return true, confirming that the string is a palindrome.

Following is the implementation of the steps discussed above:

using System;
class Program
{
// Method to check if a string is a palindrome using an iterative approach
static bool IsPalindromeIterative(string str)
{
int left = 0, right = str.Length - 1;
// Compare characters from both ends moving towards the center
while (left < right)
{
if (str[left] != str[right])
return false; // Return false if any characters don't match
left++; // Move left pointer inward
right--; // Move right pointer inward
}
return true; // Return true if all characters match
}
static void Main()
{
// Define a list of test cases including valid and invalid palindromes
string[] testCases = {
"civic", // Valid palindrome
"radar", // Valid palindrome
"level", // Valid palindrome
"deified", // Valid palindrome
"12321", // Numeric palindrome
"hello", // Not a palindrome
"world", // Not a palindrome
"Palindrome", // Not a palindrome
"madam", // Valid palindrome
"noon" // Valid palindrome
};
// Iterate through each test case and check if it's a palindrome
foreach (var testCase in testCases)
{
bool isPalindrome = IsPalindromeIterative(testCase);
// Output formatted result
Console.WriteLine($"Checking: {testCase}");
Console.WriteLine(isPalindrome
? "Result: The given string is a palindrome."
: "Result: The given string is not a palindrome.");
Console.WriteLine(new string('-', 100)); // Print a dotted line separator
}
}
}

Complexity analysis

The time complexity of the iterative solution is O(n)O(n), where nn is the length of the string. This is because the loop runs from the beginning of the string to its midpoint, comparing characters from both ends.

In terms of space complexity, the iterative solution is highly efficient, requiring O(1)O(1) additional space. It uses a fixed number of variables (left and right) to keep track of indexes.

Advantages of using two pointers:

For the iterative approach, directly compare characters in the string without creating new strings (e.g., reversing or slicing substrings) for large inputs. This can save memory and reduce runtime.

Recursive approach

The recursive approach solves the problem by comparing characters at opposite ends of the string and recursively validating the substring between those characters. If the string is empty or has only one character (base cases), it is a palindrome. Otherwise, it checks the first and last characters, and if they match, calls the function again with the substring excluding those two characters.

Steps

  1. Define a base case: Check if the left index is greater than or equal to the right index (left >= right). This means the string is either empty or has one character left, indicating it is a palindrome. Return true in this case.

  2. Compare characters: Compare the characters at the current left and right indexes (str[left] and str[right]). If the characters do not match, return false, as this means the string is not a palindrome.

  3. Make a recursive call: If the characters match, make a recursive call to IsPalindromeRecursive, incrementing the left index by 1 (left + 1) and decrementing the right index by 1 (right - 1). This effectively checks the next inner substring.

  4. Terminate on mismatch: If any recursive call encounters a mismatch in characters, it will return false, propagating this result back up the call stack.

  5. Complete recursion: If the recursion completes successfully without any mismatches, the method returns true, confirming that the string is a palindrome.

Following is the implementation of the steps discussed above:

using System;
class Program
{
// Recursive method to check if a string is a palindrome.
static bool IsPalindromeRecursive(string str, int left, int right)
{
// Base case: If left index meets or exceeds the right, it's a palindrome
if (left >= right)
{
return true;
}
// Check if the characters at the current indices are not equal
if (str[left] != str[right])
{
return false; // Not a palindrome
}
// Recursive call with next inner indices
return IsPalindromeRecursive(str, left + 1, right - 1);
}
static void Main()
{
// Test cases with valid and invalid palindromes
string[] testCases = {
"deified", // Valid palindrome
"radar", // Valid palindrome
"level", // Valid palindrome
"civic", // Valid palindrome
"madam", // Valid palindrome
"12321", // Numeric palindrome
"hello", // Not a palindrome
"world", // Not a palindrome
"Palindrome", // Not a palindrome
"noon" // Valid palindrome
};
// Check each test case
foreach (var testCase in testCases)
{
// Check if the string is a palindrome
bool isPalindrome = IsPalindromeRecursive(testCase, 0, testCase.Length - 1);
// Output formatted result
Console.WriteLine($"Checking: {testCase}");
Console.WriteLine(isPalindrome
? "Result: The given string is a palindrome."
: "Result: The given string is not a palindrome.");
Console.WriteLine(new string('-', 100));
}
}
}

Complexity analysis

The recursive solution has a time complexity of O(n)O(n), as it checks characters from both ends of the string by making recursive calls. Each call processes one pair of characters, and the recursion terminates after examining n/2n/2 pairs.

However, the space complexity of the recursive solution is O(n)O(n) due to the call stack. Each recursive call adds a new frame to the stack, and the depth of recursion corresponds to n/2n/2, or half the length of the string in the worst case.

Comparison of approaches

Both approaches are valid and provide valuable insights into solving palindrome problems in C#. Choose the one that fits your use case and personal preference!

Feature

Iterative Approach

Recursive Approach

Ease of Use

Straightforward

Slightly complex

Performance

More efficient

More memory overhead

Suitability

Best for larger strings

Best for conceptual clarity

Implementation

Simple loop with pointers

Requires understanding of recursion

Frequently asked questions

Haven’t found what you were looking for? Contact Us


Which approach is better for palindrome check: iterative or recursive?

The iterative approach is more memory-efficient and faster for large inputs, while the recursive approach is more elegant and useful for smaller inputs or learning recursion.


How do I handle case sensitivity and special characters?

Normalize the string by converting it to lowercase and removing non-alphanumeric characters using methods like char.IsLetterOrDigit.


Can an empty string be considered a palindrome?

Yes, an empty string is considered a palindrome as it reads the same backward and forward.


Is a single-character string always a palindrome?

Yes, any single-character string is a palindrome by definition.


Free Resources

Copyright ©2024 Educative, Inc. All rights reserved