VOOZH about

URL: https://www.geeksforgeeks.org/dsa/count-palindromic-subsequence-given-string/

⇱ Count All Palindromic Subsequence in a given String - GeeksforGeeks


  • Courses
  • Tutorials
  • Interview Prep

Count All Palindromic Subsequence in a given String

Last Updated : 1 Oct, 2024

Given a string s of length n, the task is to count number of palindromic subsequence (need not necessarily be distinct) present in the string s.

Example:

Input: s = "abcd"
Output: 4
Explanation: Palindromic subsequence are : "a" ,"b", "c" ,"d"

Input: s = "aab"
Output: 4
Explanation: palindromic subsequence are :"a", "a", "b", "aa"

Input: s = "geeksforgeeks"
Output: 81

Naive Recursive Approach

A very naive approach would be to generate all possible subsequences of the string and check each one to see if it's a palindrome. This approach is highly inefficient due to the exponential number of subsequences.

Steps-by-step approach:

  • Generate all subsequences of the string.
  • For each subsequence, check if it's a palindrome.
  • Count all subsequences that are palindromes.

Output
81

Time Complexity: O(n*2n), where n is the length of the string. This is because there are 2n subsequences and checking each one takes O(n).
Auxiliary Space: O(n), The recursion stack can go as deep as the length of the string n.

Memoization Approach

In the above naive approach we've generated all possible subsequences, which is inefficient due to the exponential number of combinations. We can use Memoization techique to optimize this process by storing results of computed subproblem so that we don’t need to recalculate the result for same subproblem, if it occurs.

When looking at the characters at the start and end of a substring:

  • If the characters are the same, it means we can form palindromes that include both characters.
  • If the characters are different, we need to count palindromes by ignoring one character at a time. This will helps us find all possible palindromic subsequences without missing any.

Recurrance Relation:

  • If s[i] == s[j], the number of palindromic subsequences is: count(i, j) = 1 + count(i + 1, j) + count(i, j - 1).
    The "+1" counts the new palindrome formed by s[i] and s[j].
  • If s[i] != s[j], the relation becomes: count(i, j) = count(i + 1, j) + count(i, j - 1) - count(i + 1,j - 1)
    We subtract count(i + 1, j - 1) because it is counted twice.

Output
81

Time Complexity: O(n2), The recursive function explores all pairs of indices, leading to a O(n2) number of subproblems.
Auxiliary Space: O(n2), A 2D memoization array of size n*n is used to store results of subproblems.

Dynamic Programming Approach (Buttom-up/Tabulation)

This is the most optimized approach where we use a 2D dynamic programming table to store the number of palindromic subsequences for every substring of the given string. This avoids the overhead of recursive calls and memoization.

Recurrance Relation:

Let dp[i][j] be the number of palindromic subsequences in the substring s[i...j]. The relation is the same as described in the memoized approach:

  • If s[i] == s[j]: dp[i][j] = dp[i + 1][j] + dp[i][j-1] + 1
  • If s[i] != s[j]: dp[i][j] = dp[i + 1][j] + dp[i][j - 1] - dp[i + 1][j - 1]

Output
81

Time Complexity: O(n2), Filling the DP table involves two nested loops, each running up to n.
Auxiliary Space: O(n2), A 2D DP array of size n*n is used to store results.


Comment