Length of longest Palindromic Subsequence of even length with no two adjacent characters same

Given a string str, the task is to find the length of the longest palindromic subsequence of even length with no two adjacent characters same except the middle characters.

Examples:

Input: str = “abscrcdba”
Output: 6
Explanation:
abccba is the required string which has no two consecutive characters same except the middle characters. Hence the length is 6

Input: str = “abcd”
Output: 1

Approach: The idea is to form a recursive solution and store the values of the subproblems using Dynamic Programming. The following steps can be followed to compute the result:



  • Form a recursive function which will take a string and a character which is the starting character of the subsequence.
  • If the first and last character of the string matches with the given character then remove the first and last character and call the function with all the character values from ‘a’ to ‘z’ except the given character, as the adjacent character cannot be same and find the maximum length.
  • If the first and last character of the string does not match with the given character, then find the first and last index of the given character in the string, say i, j respectively. Take the substring from i to j and call the function with substring and the given character.
  • Finally, memorise the values in an unordered map and use it if the function is again called with the same parameters.

The following is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of above approach
  
#include <bits/stdc++.h>
using namespace std;
  
#define lli long long int
  
// To store the values of subproblems
unordered_map<string, lli> dp;
  
// Function to find the
// Longest Palindromic subsequence of even
// length with no two adjacent characters same
lli solve(string s, char c)
{
    // Base cases
    // If the string length is 1 return 0
    if (s.length() == 1)
        return 0;
  
    // If the string length is 2
    if (s.length() == 2) {
  
        // Check if the characters match
        if (s[0] == s[1] && s[0] == c)
            return 1;
        else
            return 0;
    }
  
    // If the value with given parameters is
    // previously calculated
    if (dp[s + " " + c])
        return dp[s + " " + c];
  
    lli ans = 0;
  
    // If the first and last character of the
    // string matches with the given character
    if (s[0] == s[s.length() - 1] && s[0] == c) {
  
        // Remove the first and last character
        // and call the function for all characters
        for (char c1 = 'a'; c1 <= 'z'; c1++)
  
            if (c1 != c)
                ans = max(
                    ans,
                    1 + solve(
                            s.substr(
                                1, s.length() - 2),
                            c1));
    }
  
    // If it does not match
    else {
  
        // Then find the first and last index of
        // given character in the given string
        for (lli i = 0; i < s.length(); i++) {
  
            if (s[i] == c) {
                for (lli j = s.length() - 1; j > i; j--)
                    if (s[j] == c) {
                        if (j == i)
                            break;
  
                        // Take the substring from i
                        // to j and call the function
                        // with substring
                        // and the given character
                        ans = solve(
                            s.substr(i, j - i + 1),
                            c);
                        break;
                    }
  
                break;
            }
        }
    }
  
    // Store the answer for future use
    dp[s + " " + c] = ans;
    return dp[s + " " + c];
}
  
// Driver code
int main()
{
    string s = "abscrcdba";
  
    lli ma = 0;
  
    // Check for all starting characters
    for (char c1 = 'a'; c1 <= 'z'; c1++)
        ma = max(ma, solve(s, c1) * 2);
    cout << ma << endl;
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of above approach
import java.util.*;
  
class GFG
{
  
    // To store the values of subproblems
    static Map<String, Integer> dp = new HashMap<>();
  
    // Function to find the
    // Longest Palindromic subsequence of even
    // length with no two adjacent characters same
    static Integer solve(char[] s, char c) 
    {
          
        // Base cases
        // If the String length is 1 return 0
        if (s.length == 1)
            return 0;
  
        // If the String length is 2
        if (s.length == 2
        {
  
            // Check if the characters match
            if (s[0] == s[1] && s[0] == c)
                return 1;
            else
                return 0;
        }
  
        // If the value with given parameters is
        // previously calculated
        if (dp.containsKey(String.valueOf(s) + " " + c))
            return dp.get(String.valueOf(s) + " " + c);
        Integer ans = 0;
  
        // If the first and last character of the
        // String matches with the given character
        if (s[0] == s[s.length - 1] && s[0] == c) 
        {
  
            // Remove the first and last character
            // and call the function for all characters
            for (char c1 = 'a'; c1 <= 'z'; c1++)
  
                if (c1 != c)
                    ans = Math.max(ans, 1 +
                            solve(Arrays.copyOfRange(s,
                            1, s.length - 1), c1));
        }
  
        // If it does not match
        else 
        {
  
            // Then find the first and last index of
            // given character in the given String
            for (Integer i = 0; i < s.length; i++)
            {
  
                if (s[i] == c) 
                {
                    for (Integer j = s.length - 1; j > i; j--)
                        if (s[j] == c)
                        {
                            if (j == i)
                                break;
  
                            // Take the subString from i
                            // to j and call the function
                            // with subString
                            // and the given character
                            ans = solve(Arrays.copyOfRange(s,
                                        i, j + 1), c);
                            break;
                        }
  
                    break;
                }
            }
        }
  
        // Store the answer for future use
        dp.put(String.valueOf(s) + " " + c, ans);
        return dp.get(String.valueOf(s) + " " + c);
    }
  
    // Driver code
    public static void main(String[] args) 
    {
        String s = "abscrcdba";
  
        Integer ma = 0;
  
        // Check for all starting characters
        for (char c1 = 'a'; c1 <= 'z'; c1++)
            ma = Math.max(ma, solve(s.toCharArray(), c1) * 2);
        System.out.print(ma + "\n");
  
    }
}
  
// This code is contributed by 29AjayKumar

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of above approach 
  
# To store the values of subproblems 
dp = {}; 
  
# Function to find the 
# Longest Palindromic subsequence of even 
# length with no two adjacent characters same 
def solve(s, c) : 
      
    # Base cases 
    # If the string length is 1 return 0 
    if (len(s) == 1) :
        return 0
  
    # If the string length is 2 
    if (len(s) == 2) :
  
        # Check if the characters match 
        if (s[0] == s[1] and s[0] == c) :
            return 1
        else :
            return 0
      
    # If the value with given parameters is 
    # previously calculated 
    if (s + " " + c) in dp : 
        return dp[s + " " + c]; 
  
    ans = 0
  
    # If the first and last character of the 
    # string matches with the given character 
    if (s[0] == s[len(s) - 1] and s[0] == c) :
  
        # Remove the first and last character 
        # and call the function for all characters 
        for c1 in range(97,123) :
  
            if (chr(c1) != c) :
                ans = max( ans, 1 + solve(
                        s[1 : len(s) - 1], chr(c1))); 
      
  
    # If it does not match 
    else :
          
        # Then find the first and last index of 
        # given character in the given string 
        for i in range(len(s)) : 
  
            if (s[i] == c) :
                for j in range(len(s) - 1, i, -1) :
                    if (s[j] == c) :
                        if (j == i) :
                            break
  
                        # Take the substring from i 
                        # to j and call the function 
                        # with substring 
                        # and the given character 
                        ans = solve( s[i : j - i + 2], c); 
                        break
  
                break
          
    # Store the answer for future use 
    dp[s + " " + c] = ans;
      
    return dp[s + " " + c]; 
  
# Driver code 
if __name__ == "__main__"
  
    s = "abscrcdba"
  
    ma = 0
  
    # Check for all starting characters 
    for c1 in range(97,123) :
        ma = max(ma, solve(s, chr(c1)) * 2); 
      
    print(ma); 
      
# This code is contributed by AnkitRai01

chevron_right


Output:

6

Related Article: Longest Palindromic Subsequence

Don’t stop now and take your learning to the next level. Learn all the important concepts of Data Structures and Algorithms with the help of the most trusted course: DSA Self Paced. Become industry ready at a student-friendly price.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : AnkitRai01, 29AjayKumar