Open In App

Total number of odd length palindrome sub-sequence around each center

Last Updated : 20 Dec, 2022
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a string str, the task is to find the number of odd length palindromic sub-sequences around of str with str[i] as center i.e. every index will be considered as the center one by one.

Examples: 

Input: str = "xyzx" 
Output: 1 2 2 1 
For index 0: There is only a single sub-sequence possible i.e. "x" 
For index 1: Two sub-sequences are possible i.e. "y" and "xyx" 
For index 2: "z" and "xzx" 
For index 3: "x"

Input: str = "aaaa" 
Output: 1 3 3 1 

Approach: We will use dynamic programming to solve this problem. Let's denote length of the string str be N. Now, Let dp[i][j] denote the number of palindromic sub-sequences from 0 to i - 1 and number of palindromic sub-sequences from j to N - 1
Let len be the distance between i and j. For each length len, we will fix our i and j, and check whether characters str[i] and str[j] are equal or not. Then according to it, we will make our dp transitions. 

If str[i] != str[j] then dp[i][j] = dp[i - 1][j] + dp[i][j + 1] - dp[i - 1][j + 1] 
If str[i] == str[j] then dp[i][j] = dp[i - 1][j] + dp[i][j + 1]
Base case: 
If i == 0 and j == n - 1 then dp[i][j] = 2 if str[i] == str[j] else dp[i][j] = 1
 

Below is the implementation of the above approach:  

C++
// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;

// Function to find the total palindromic
// odd length sub-sequences
void solve(string& s)
{
    int n = s.length();

    // dp array to store the number of palindromic
    // subsequences for 0 to i-1 and j+1 to n-1
    int dp[n][n];
    memset(dp, 0, sizeof dp);

    // We will start with the largest
    // distance between i and j
    for (int len = n - 1; len >= 0; --len) {

        // For each len, we fix our i
        for (int i = 0; i + len < n; ++i) {

            // For this i we will find our j
            int j = i + len;

            // Base cases
            if (i == 0 and j == n - 1) {
                if (s[i] == s[j])
                    dp[i][j] = 2;
                else if (s[i] != s[j])
                    dp[i][j] = 1;
            }
            else {
                if (s[i] == s[j]) {

                    // If the characters are equal
                    // then look for out of bound index
                    if (i - 1 >= 0) {
                        dp[i][j] += dp[i - 1][j];
                    }
                    if (j + 1 <= n - 1) {
                        dp[i][j] += dp[i][j + 1];
                    }
                    if (i - 1 < 0 or j + 1 >= n) {

                        // We have only 1 way that is to
                        // just pick these characters
                        dp[i][j] += 1;
                    }
                }
                else if (s[i] != s[j]) {

                    // If the characters are not equal
                    if (i - 1 >= 0) {
                        dp[i][j] += dp[i - 1][j];
                    }
                    if (j + 1 <= n - 1) {
                        dp[i][j] += dp[i][j + 1];
                    }
                    if (i - 1 >= 0 and j + 1 <= n - 1) {

                        // Subtract it as we have
                        // counted it twice
                        dp[i][j] -= dp[i - 1][j + 1];
                    }
                }
            }
        }
    }
    vector<int> ways;
    for (int i = 0; i < n; ++i) {
        if (i == 0 or i == n - 1) {

            // We have just 1 palindrome
            // sequence of length 1
            ways.push_back(1);
        }
        else {

            // Else total ways would be sum of dp[i-1][i+1],
            // that is number of palindrome sub-sequences
            // from 1 to i-1 + number of palindrome
            // sub-sequences from i+1 to n-1
            int total = dp[i - 1][i + 1];
            ways.push_back(total);
        }
    }
    for (int i = 0; i < ways.size(); ++i) {
        cout << ways[i] << " ";
    }
}

// Driver code
int main()
{
    string s = "xyxyx";
    solve(s);

    return 0;
}
Java
// Java implementation of above approach
import java.util.*;

class GFG 
{

// Function to find the total palindromic
// odd length sub-sequences
static void solve(char[] s)
{
    int n = s.length;

    // dp array to store the number of palindromic
    // subsequences for 0 to i-1 and j+1 to n-1
    int [][]dp = new int[n][n];

    // We will start with the largest
    // distance between i and j
    for (int len = n - 1; len >= 0; --len) 
    {

        // For each len, we fix our i
        for (int i = 0; i + len < n; ++i)
        {

            // For this i we will find our j
            int j = i + len;

            // Base cases
            if (i == 0 && j == n - 1) 
            {
                if (s[i] == s[j])
                    dp[i][j] = 2;
                else if (s[i] != s[j])
                    dp[i][j] = 1;
            }
            else
            {
                if (s[i] == s[j]) 
                {

                    // If the characters are equal
                    // then look for out of bound index
                    if (i - 1 >= 0) 
                    {
                        dp[i][j] += dp[i - 1][j];
                    }
                    if (j + 1 <= n - 1) 
                    {
                        dp[i][j] += dp[i][j + 1];
                    }
                    if (i - 1 < 0 || j + 1 >= n) 
                    {

                        // We have only 1 way that is to
                        // just pick these characters
                        dp[i][j] += 1;
                    }
                }
                else if (s[i] != s[j])
                {

                    // If the characters are not equal
                    if (i - 1 >= 0) 
                    {
                        dp[i][j] += dp[i - 1][j];
                    }
                    if (j + 1 <= n - 1) 
                    {
                        dp[i][j] += dp[i][j + 1];
                    }
                    if (i - 1 >= 0 && j + 1 <= n - 1) 
                    {

                        // Subtract it as we have
                        // counted it twice
                        dp[i][j] -= dp[i - 1][j + 1];
                    }
                }
            }
        }
    }
    
    Vector<Integer> ways = new Vector<>();
    for (int i = 0; i < n; ++i) 
    {
        if (i == 0 || i == n - 1) 
        {

            // We have just 1 palindrome
            // sequence of length 1
            ways.add(1);
        }
        else 
        {

            // Else total ways would be sum of dp[i-1][i+1],
            // that is number of palindrome sub-sequences
            // from 1 to i-1 + number of palindrome
            // sub-sequences from i+1 to n-1
            int total = dp[i - 1][i + 1];
            ways.add(total);
        }
    }
    for (int i = 0; i < ways.size(); ++i) 
    {
        System.out.print(ways.get(i) + " ");
    }
}

// Driver code
public static void main(String[] args)
{
    char[] s = "xyxyx".toCharArray();
    solve(s);
}
}

// This code has been contributed by 29AjayKumar
Python3
# Function to find the total palindromic
# odd Length sub-sequences
def solve(s):
    n = len(s)

    # dp array to store the number of palindromic
    # subsequences for 0 to i-1 and j+1 to n-1
    dp=[[0 for i in range(n)] for i in range(n)]

    # We will start with the largest
    # distance between i and j
    for Len in range(n-1,-1,-1):

        # For each Len, we fix our i
        for i in range(n):

            if i + Len >= n:
                break

            # For this i we will find our j
            j = i + Len

            # Base cases
            if (i == 0 and j == n - 1):
                if (s[i] == s[j]):
                    dp[i][j] = 2
                elif (s[i] != s[j]):
                    dp[i][j] = 1
            else:
                if (s[i] == s[j]):
                    # If the characters are equal
                    # then look for out of bound index
                    if (i - 1 >= 0):
                        dp[i][j] += dp[i - 1][j]

                    if (j + 1 <= n - 1):
                        dp[i][j] += dp[i][j + 1]

                    if (i - 1 < 0 or j + 1 >= n):

                        # We have only 1 way that is to
                        # just pick these characters
                        dp[i][j] += 1

                elif (s[i] != s[j]):

                    # If the characters are not equal
                    if (i - 1 >= 0):
                        dp[i][j] += dp[i - 1][j]

                    if (j + 1 <= n - 1):
                        dp[i][j] += dp[i][j + 1]

                    if (i - 1 >= 0 and j + 1 <= n - 1):

                        # Subtract it as we have
                        # counted it twice
                        dp[i][j] -= dp[i - 1][j + 1]

    ways = []
    for i in range(n):
        if (i == 0 or i == n - 1):

            # We have just 1 palindrome
            # sequence of Length 1
            ways.append(1)
        else:

            # Else total ways would be sum of dp[i-1][i+1],
            # that is number of palindrome sub-sequences
            # from 1 to i-1 + number of palindrome
            # sub-sequences from i+1 to n-1
            total = dp[i - 1][i + 1]
            ways.append(total)

    for i in ways:
        print(i,end=" ")

# Driver code

s = "xyxyx"
solve(s)

# This code is contributed by mohit kumar 29
C#
// C# implementation of above approach 
using System;
using System.Collections.Generic;

class GFG 
{ 

    // Function to find the total palindromic 
    // odd length sub-sequences 
    static void solve(char[] s) 
    { 
        int n = s.Length; 
    
        // dp array to store the number of palindromic 
        // subsequences for 0 to i-1 and j+1 to n-1 
        int [,]dp = new int[n, n]; 
    
        // We will start with the largest 
        // distance between i and j 
        for (int len = n - 1; len >= 0; --len) 
        { 
    
            // For each len, we fix our i 
            for (int i = 0; i + len < n; ++i) 
            { 
    
                // For this i we will find our j 
                int j = i + len; 
    
                // Base cases 
                if (i == 0 && j == n - 1) 
                { 
                    if (s[i] == s[j]) 
                        dp[i, j] = 2; 
                    else if (s[i] != s[j]) 
                        dp[i, j] = 1; 
                } 
                else
                { 
                    if (s[i] == s[j]) 
                    { 
    
                        // If the characters are equal 
                        // then look for out of bound index 
                        if (i - 1 >= 0) 
                        { 
                            dp[i, j] += dp[i - 1, j]; 
                        } 
                        if (j + 1 <= n - 1) 
                        { 
                            dp[i, j] += dp[i, j + 1]; 
                        } 
                        if (i - 1 < 0 || j + 1 >= n) 
                        { 
    
                            // We have only 1 way that is to 
                            // just pick these characters 
                            dp[i, j] += 1; 
                        } 
                    } 
                    else if (s[i] != s[j]) 
                    { 
    
                        // If the characters are not equal 
                        if (i - 1 >= 0) 
                        { 
                            dp[i, j] += dp[i - 1, j]; 
                        } 
                        if (j + 1 <= n - 1) 
                        { 
                            dp[i, j] += dp[i, j + 1]; 
                        } 
                        if (i - 1 >= 0 && j + 1 <= n - 1) 
                        { 
    
                            // Subtract it as we have 
                            // counted it twice 
                            dp[i, j] -= dp[i - 1, j + 1]; 
                        } 
                    } 
                } 
            } 
        } 
        
        List<int> ways = new List<int>();

        for (int i = 0; i < n; ++i) 
        { 
            if (i == 0 || i == n - 1) 
            { 
    
                // We have just 1 palindrome 
                // sequence of length 1 
                ways.Add(1); 
            } 
            else
            { 
    
                // Else total ways would be sum of dp[i-1][i+1], 
                // that is number of palindrome sub-sequences 
                // from 1 to i-1 + number of palindrome 
                // sub-sequences from i+1 to n-1 
                int total = dp[i - 1,i + 1]; 
                ways.Add(total); 
            } 
        } 
        for (int i = 0; i < ways.Capacity; ++i) 
        { 
            Console.Write(ways[i] + " "); 
        } 
    } 
    
    // Driver code 
    public static void Main() 
    { 
        char[] s = "xyxyx".ToCharArray(); 
        solve(s); 
    } 
} 

// This code is contributed by AnkitRai01
JavaScript
<script>
// Javascript implementation of above approach

// Function to find the total palindromic
// odd length sub-sequences
function solve(s)
{
    n = s.length;
 
    // dp array to store the number of palindromic
    // subsequences for 0 to i-1 and j+1 to n-1
    let dp = new Array(n);
    for(let i=0;i<n;i++)
    {
        dp[i]=new Array(n);
        for(let j=0;j<n;j++)
            dp[i][j]=0;
    }
 
    // We will start with the largest
    // distance between i and j
    for (let len = n - 1; len >= 0; --len)
    {
 
        // For each len, we fix our i
        for (let i = 0; i + len < n; ++i)
        {
 
            // For this i we will find our j
            let j = i + len;
 
            // Base cases
            if (i == 0 && j == n - 1)
            {
                if (s[i] == s[j])
                    dp[i][j] = 2;
                else if (s[i] != s[j])
                    dp[i][j] = 1;
            }
            else
            {
                if (s[i] == s[j])
                {
 
                    // If the characters are equal
                    // then look for out of bound index
                    if (i - 1 >= 0)
                    {
                        dp[i][j] += dp[i - 1][j];
                    }
                    if (j + 1 <= n - 1)
                    {
                        dp[i][j] += dp[i][j + 1];
                    }
                    if (i - 1 < 0 || j + 1 >= n)
                    {
 
                        // We have only 1 way that is to
                        // just pick these characters
                        dp[i][j] += 1;
                    }
                }
                else if (s[i] != s[j])
                {
 
                    // If the characters are not equal
                    if (i - 1 >= 0)
                    {
                        dp[i][j] += dp[i - 1][j];
                    }
                    if (j + 1 <= n - 1)
                    {
                        dp[i][j] += dp[i][j + 1];
                    }
                    if (i - 1 >= 0 && j + 1 <= n - 1)
                    {
 
                        // Subtract it as we have
                        // counted it twice
                        dp[i][j] -= dp[i - 1][j + 1];
                    }
                }
            }
        }
    }
     
    let ways = [];
    for (let i = 0; i < n; ++i)
    {
        if (i == 0 || i == n - 1)
        {
 
            // We have just 1 palindrome
            // sequence of length 1
            ways.push(1);
        }
        else
        {
 
            // Else total ways would be sum of dp[i-1][i+1],
            // that is number of palindrome sub-sequences
            // from 1 to i-1 + number of palindrome
            // sub-sequences from i+1 to n-1
            let total = dp[i - 1][i + 1];
            ways.push(total);
        }
    }
    for (let i = 0; i < ways.length; ++i)
    {
        document.write(ways[i] + " ");
    }
}

// Driver code
let s = "xyxyx".split("");
solve(s);

// This code is contributed by rag2127
</script>

Output: 
1 3 4 3 1

 

Time Complexity: O(n2)
Auxiliary Space: O(n2), where n is the length of the given string.


Next Article

Similar Reads