Given a string, check if the string can become palindrome by removing at-most one character from the string. The order of the characters in the string should remain same.
Example
"abca" "abc" "ymdadmt" Output: true // removing 'c' will make the string palindrome "aba" false false
Naïve solution: Valid Palindrome
Convert the string to array of characters, then iterate the array and in each iteration, filter out the element at current index and check if filtered array is palindrome or not.
const solution = (s) => { //split the string to array of characters const arr = s.split(""); //iterate array and check if palindrome can be found for(let i = 0; i < arr.length; i++){ //if palindrome is found if(isPalindrome(arr, i)){ return true; } } //if no palindrome found return false; } const isPalindrome = (arr, index) => { // remove the character from the array const filtered = arr.filter((e, i) => i !== index); //length of the filtered array const n = filtered.length; //check if filtered array is palindrome for(let i = 0; i < n / 2; i++){ if(filtered[i] !== filtered[n - i - 1]){ return false; } } return true; }
Input: const str = "ab"; console.log(solution(str)); Output: true
Time complexity: O(n ^ 2).
Space complexity: O(n).
Efficient solution
Conceptually this is how it works,
- Use two strings, one is normal and other is reversed.
- Iterate the original string and in each iteration, remove the i'th character from the beginning in the normal string and from rear in the reversed string.
- After removing the characters, if both the string matches that means they are palindrome.
- For example, consider this string
"yadmda"
, now reversed string will be"admday"
, if we start iterating the original string and remove the character at 0'th index form start and end then we will get"admda"
andadmda
, which are same.
// remove the i'th character from the string const cut = (s, i) => s.substr(0, i) + s.substr(i + 1); const solution = (s, n = s.length) => { // revesed string const reversed = s.split("").reverse().join(""); //base case if(reversed === s){ return true; } //iterate array and check if palindrome can be found for(let i = 0; i < n; i++){ //index from start const start = i; //index from rear const end = n - i - 1; //get the updated string by removing the characters const nTransformed = cut(s, start); const rTransformed = cut(reversed, end); //if both string match, then it is palindrome if(nTransformed === rTransformed){ return true; } } //if no palindrome found return false; }
Input: const str = "ab"; console.log(solution(str)); Output: true
Time complexity: O(n).
Space complexity: O(n).