C++ Program for Longest subsequence of a number having same left and right rotation


In this problem, we need to find the maximum length of the sub sequence with the same left and right rotations. The left rotation means moving all characters of the string in the left direction and the first character at the end. The right rotation means moving all string characters in the right direction and the last character at the start.

Problem statement – We have given string str containing numeric digits and need to find the sub sequence of maximum length with the same left and right rotations.

Sample examples

Input – str = "323232",

Output – 6

Explanation– The longest sub sequence having the same left and right rotation is ‘323232’. The left rotation is ‘232323’, and the right rotation is ‘232323’.

Input – str = ‘00010100’

Output – 6

Explanation – The longest sub sequence having the same left and right rotation is ‘000000’.

Input – str = ‘092312110431010’

Output – 6

Explanation – There are 2 possible sub sequences of length 6 with the same left and right rotations. The first is ‘010101’, and the second is ‘101010’.

Approach 1

In this approach, we will find all possible sub sequences of the given string. After that, we will check whether the left and right rotation of the string is the same. We will use the recursive approach to find all possible sub-sequences.

Algorithm

  • Initialize the ‘maxLen’ global variable with zero to store the length of the longest sub-sequence having the same left and right rotations.

  • Define the isRightSameLeft() function to check whether the string has the same left and right rotation.

    • Inside the function, use the substr() method to rotate the string left and right.

  • The getAllSubSeq() function is used to find all possible sub-sequences of the given string.

  • Define the base case. If ‘str’ is empty, we get the sub-sequence and execute the isRightSameLeft() function to check whether the sub-sequence has the same left and right rotation. If yes, update the ‘maxLen’ variable’s value if its length is bigger than the current value of ‘maxLen’.

  • Make a recursive call after removing the first character from the ‘str’ and appending it with the ‘out’ string.

  • Make a recursive function call again after removing the first character and keeping the ‘out’ string as it is. In this recursive call, we exclude the first character of ‘str’.

Example

#include <iostream>
#include <string>
using namespace std;

// Defining global variable to store the length of the longest subsequence according to the given condition
int maxLen = 0;
//  function to check if the string is the same after the left rotation
bool isRightSameLeft(string str) {
   int len = str.length();
   return str.substr(1, len - 1) + str[0] == str[len - 1] + str.substr(0, len - 1);
}
// function to get all subsequences of a string
void getAllSubSeqs(string str, string out) {
   // If the string is empty, we get the subsequences. Check if its left and right rotation is the same
   if (str.empty()) {
      if (isRightSameLeft(out))
          maxLen = max(maxLen, (int)out.length());
      return;
   }
   // Recursive case remove the first character from str, and add it to the output
   getAllSubSeqs(str.substr(1), out + str[0]);
   // remove the first character from str, and drop it
   if (str.length() > 1)
      getAllSubSeqs(str.substr(1), out);
}
int main() {
   string str = "323232";
   string out = "";
   getAllSubSeqs(str, out);
   cout << "The longest subsequence of str having same left and right rotation is " << maxLen;
   return 0;
}

Output

The longest subsequence of str having same left and right rotation is 6

Time complexity – O(N*2N). Here O(N) is for comparing the left and right rotation, and O(2N) is for finding all possible subsequences.

Space complexity – O(1) as we don’t use extra space.

Approach 2

Here, we have optimized the above approach. We can observe the solutions of the sample input. The left and right rotations of the subsequence are only the same if the subsequence contains the same characters or two different characters alternatively, and the length is even.

Algorithm

  • Use two nested loops to make combinations of any two digits.

  • Define the ‘cnt’ variable to find the length of the subsequence containing two digits alternatively and initialize with zero.

  • Define the ‘first’ variable of the boolean type to track whether the next character should be ith or jth.

  • Use the loop to traverse the string.

  • If first == true and str[k] - '0' == I, alternate the value of ‘first’ and increment ‘cnt’ by 1.

  • If first == false and str[k] - '0' == j, again alternate the value of ‘first’ and increment ‘cnt’ by 1.

  • If i and j are not equal, and the ‘cnt’ value is odd, decrease it by 1.

  • Update the value of the ‘res’ variable if the cnt value is greater than ‘res’.

Example

#include <bits/stdc++.h>
using namespace std;

int getLongSubSeq(string str) {
   // Store the length of the string
   int len = str.size(), res = 0;
   // Traverse the all possible combination of two digits
   for (int i = 0; i < 10; i++) {
      for (int j = 0; j < 10; j++) {
          // to store the length of an alternating sequence of the current combination
          int cnt = 0;
          // to track the turn of the ith or jth digit
          bool first = true;
          // traverse the string
          for (int k = 0; k < len; k++) {
              // If the current digit is equal to I, and the first is true, increment the count
              if (first == true and str[k] - '0' == i) {
                  first = false;
                  cnt++;
              } else if (first == false and str[k] - '0' == j) {
                  // If the current digit is equal to j, and the first is false, increment the count
                  first = true;
                  cnt++;
              }
          }
          // If the sequence is odd and i and j are different, decrement the count
          if (i != j and cnt % 2 == 1)
              cnt--;
          // Update the answer
          res = max(cnt, res);
       }
   }
   return res;
}
int main() {
   string str = "00010100";
   cout << "The longest subsequence of str having same left and right rotation is " << getLongSubSeq(str);
   return 0;
}

Output

The longest subsequence of str having same left and right rotation is 6

Time complexity – O(10*10*N) as we find subsequence from the string containing digits combination.

Space complexity – O(1), as we don’t use dynamic space.

This tutorial taught us two approaches to finding the longest subsequence containing the same left and right rotation. The first approach is the naïve approach, which is very time expensive, and we can’t use it for large inputs.

The second approach is optimized as its time complexity almost equals the O(N).

Updated on: 17-Aug-2023

45 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements