Number of palindromic subsequences of length k where k <= 3


Palindromes are series of letters, numbers or characters which have same starting and ending point. Also, they are same when read from left to right and right to left.

A subsequence of a string is a new string which is made by removing some of the characters from the original string without changing the relative order of the characters which are remaining. Suppose you are given a string of length N.

You want to find palindromic subsequences of length K from the string. Note that value of K can be less than or equal to 3. In this article, we will find the number of these subsequences using C++.

Input Output Scenarios

We are given the string and K. The number of palindromic subsequences of length K in that string is the output.

Input: str = "aabaabb", K = 2
Output: 9
Input: str = "xxyyyxxzzy", K = 3
Output: 32

Here, in case of str = "aabaabb" and K = 2, we have 9 possible subsequences. They are aa, aa, aa, aa, aa, aa, bb, bb, bb.

In case of K = 1, the result will be equal to length of the string. In case of K = 2,

Using Recursion

We will use recursion to find all possible subsequences of length K from the given string. First, we will create a Boolean function which checks whether a string is palindromic or not. Next, we create a function palindromicSubsequences to find total possible counts.

In this function, we use recursion to find all possible combinations of length K from the string. Then, we check whether the new string is palindromic or not using the Boolean function. If the condition is true then, the count variable is increased by one.

Example

#include <iostream>
#include <string>
using namespace std;
bool palindrome(const string& str) {
   int start = 0, end = str.length() - 1;
   while (start < end) {
      if (str[start] != str[end]) {
         return false;
      }
      start++;
      end--;
   }
   return true;
}
int palindromicSubsequences(string str, int K, int begin, string sub, int
&count) {
   for (int i = begin; i < str.length(); i++) {
      sub += str[i];
      palindromicSubsequences(str, K, i + 1, sub, count);
      sub.pop_back();
   }
   if (sub.length() == K) {
      if (palindrome(sub)) {
         count++;
      }
   }
   return count;
}
int main() {
   string str = "xxyyyxxzzy";
   int K = 3;
   int count = 0;
   int result = palindromicSubsequences(str, K, 0, "", count);
   cout << "Number of palindromic subsequences of length " << K << " in the string " << str << ": " << result << endl;
   return 0;
}

Output

Number of palindromic subsequences of length 3 in the string xxyyyxxzzy: 32

Using Arrays

We will first compute left and right characters of the subsequences to find the information about the frequency of the characters. Next, we iterate through all the elements of the string and check whether the left and right characters of the subsequences are palindromic or not.

Example

#include <iostream>
#define MAX 100
using namespace std;
const int max_value = 52;
void palindrome(string str, int N, int left[][MAX], int right[][MAX]) {
   for (int i = 0; i < max_value; i++) {
      for (int j = 0; j < N; j++) {
         left[i][j] = 0;
         right[i][j] = 0;
      }
   }
   left[str[0] - 'x'][0] = 1;
   for (int i = 1; i < N; i++) {
      for (int j = 0; j < max_value; j++) {
         left[j][i] += left[j][i - 1];
         if (str[i] - 'x' == j) {
            left[j][i]++;
         }
      }
   }
   right[str[N - 1] - 'x'][N - 1] = 1;
   for (int i = N - 2; i >= 0; i--) {
      for (int j = 0; j < max_value; j++) {
         right[j][i] += right[j][i + 1];
         if (str[i] - 'x' == j) {
            right[j][i]++;
         }
      }
   }
}
int palindromicSubsequences(int K, int N, int left[][MAX], int right[][MAX]) {
   int count = 0;
   if (K == 1) {
      for (int i = 0; i < max_value; i++)
      count += left[i][N - 1];
      return count;
   }
   if (K == 2) {
      count = 0;
      for (int i = 0; i < max_value; i++) {
         count += (left[i][N - 1] * (left[i][N - 1] - 1)) / 2;
      }
      return count;
   }
   for (int i = 1; i < N - 1; i++) {
      for (int j = 0; j < max_value; j++) {
         count += left[j][i - 1] * right[j][i + 1];
      }
   }
   return count;
}
int main() {
   string str = "xxyyyxxzzy";
   int N = str.length();
   int K = 3;
   int left[max_value][MAX] = {
      0
   }, right[max_value][MAX] = {
      0
   };
   palindrome(str, N, left, right);
   int result = palindromicSubsequences(K, N, left, right);
   cout << "Number of palindromic subsequences of length " << K << " in the string " << str << ": " << result << endl;
   return 0;
}

Output

Number of palindromic subsequences of length 3 in the string xxyyyxxzzy: 32

Conclusion

We have discussed about different ways to find the number of palindromic subsequences in a string. The first approach is a simple one using recursion and permutation. The second approach uses precomputation of data in arrays to increase the efficiency of the code.

Updated on: 05-Jan-2024

97 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements