Valid Palindrome II easy
Problem Statement
Given a string s
, return true
if it is a palindrome, or if it can be made a palindrome by removing at most one character.
Example 1
Input: s = "aba" Output: true Explanation: "aba" is already a palindrome.
Example 2
Input: s = "abca" Output: true Explanation: You could remove the character 'c' to make "aba" which is a palindrome.
Steps
- Check if the string is already a palindrome: If it is, return
true
. - Iterate through the string: Compare characters from the beginning and end, moving inwards.
- Handle discrepancies: If characters don't match, we have two options:
- Remove the character at the beginning and check if the remaining substring is a palindrome.
- Remove the character at the end and check if the remaining substring is a palindrome.
- If either of these results in a palindrome, return
true
.
- Return false: If no solution is found after checking all discrepancies, return
false
.
Explanation
The solution efficiently checks if a string is a palindrome or can be made one by removing at most one character. The core logic lies in handling mismatches between characters at the beginning and end of the string. By recursively checking the substring after removing either the beginning or end character, we explore all possible single-character removals to determine if a palindrome can be formed.
The use of helper function IsPalindrome
avoids repetitive code and improves readability. The string.Substring
method is used for efficiently creating substrings without unnecessary copying.
Code
using System;
public class Solution {
public bool ValidPalindrome(string s) {
if (IsPalindrome(s)) return true;
for (int i = 0; i < s.Length; i++) {
string s1 = s.Substring(0, i) + s.Substring(i + 1);
if (IsPalindrome(s1)) return true;
}
return false;
}
private bool IsPalindrome(string s) {
int left = 0;
int right = s.Length - 1;
while (left < right) {
if (s[left] != s[right]) return false;
left++;
right--;
}
return true;
}
}
Complexity
- Time Complexity: O(N), where N is the length of the string. In the worst case, we might iterate through the string once to check if it's a palindrome, and then iterate through it again to check at most N - 1 substrings after removing one character. The
IsPalindrome
helper function takes O(N/2) which simplifies to O(N). - Space Complexity: O(N) in the worst case due to the substring creation in the
ValidPalindrome
function. However, the space used is proportional to the length of the string, and not exponentially increasing. This can be slightly optimized using two pointers without substring creation, resulting in O(1) space complexity (see optimized solution below).
Optimized Code (O(1) Space Complexity)
using System;
public class Solution {
public bool ValidPalindrome(string s) {
int left = 0;
int right = s.Length - 1;
while (left < right) {
if (s[left] != s[right]) {
return IsPalindrome(s, left + 1, right) || IsPalindrome(s, left, right - 1);
}
left++;
right--;
}
return true;
}
private bool IsPalindrome(string s, int left, int right) {
while (left < right) {
if (s[left] != s[right]) return false;
left++;
right--;
}
return true;
}
}
This optimized version avoids the creation of substrings, improving space complexity to O(1). It directly uses pointers within the original string.