Longest subsequence with different adjacent characters


Introduction

In this tutorial, we implement an approach to find the longest subsequence with different adjacent characters. Here, the longest subsequence is a subsequence that contains the maximum number of string characters with different adjacent characters. To implement the approach to finding the longest subsequence, consider a string s, and iterate

We use two approaches to resolve the problem statement of finding the longest subsequence having different adjacent characters.

  • Greedy Approach

    It is one of the most used algorithms to solve the data structure problem. This approach tries all possible cases and chooses the most suitable.

  • Dynamic programming

    It is an improved and less time-consuming approach to greedy algorithms. Dynamic programming divides tasks into chunks and solves each independently to find the most effective solution.

Demonstration 1

Input = String = "xyyx"
Output = The longest subsequence with different adjacent characters is xy

Explanation

In the above input string "xyyx" the longest possible subsequence is 'xy' as its adjacent characters are different. In the longest subsequence, the adjacent character of 'x' is 'y', and for 'y' is 'x'. There are no repeating neighboring characters in the Output subsequence.

Demonstration 2

Input = String = "xyzyy"
Output = The longest subsequence with different adjacent characters is xyz.

Explanation

In the above input string "xyzyy", the longest possible subsequence is 'xyzy' with different adjacent characters. Here, the adjacent characters of 'y' are 'x' and 'z'. The adjacent character of 'x' is 'y' and adjacent to 'z' is 'y'.

C++ Library Functions

  • size() − It is a predefined library function in C++ standard library. It returns the length of the input string.

string_name.size();
  • back() − This string class library function is defined in the <string> header file. It returns the reference of the last character of the string.

string_name.back();
  • empty() − It is a predefined function in the <string> header file. It checks whether the length of the string is 0 or not, which means the string is empty or not.

string_name.empty();
  • memset() − This library function is defined in the <cstring> header file. It allocates memory blocks for some values. It takes 3 parameters: dest, ch, and cnt. Des is the source to be copied, ch is the characters and cnt is the number of blocks.

memset(dest, ch, cnt);
  • length() − It is a string class library function defined in the <string> header file. It returns the length of the input string in bytes form. The length of the string is the number of characters.

string_name.length();

Algorithm

  • Take an input string.

  • Iterate through each character of the input string.

  • Store the first character in a string variable and compare it with the next character.

  • If the character is different from the previous character, store it in a string variable else reject this character.

  • Repeat step 4 till find the longest subsequence with different adjacent characters.

  • Print the result.

Example 1

In this C++ implementation, longestSubsequence() returns the maximum length or longest subsequence using the input string. Iterates through the input string characters to find the longest subsequence whose adjacent characters are different. It uses a greedy approach to find the most efficient Output.

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

//finding the longest subsequence having different adjacent characters
string longestSubsequence(const string& input) {
   string subsequence;
   string result;

   //iterating each character of the input string
   for (char ch : input) {
      if (result.empty() || ch != result.back()) {
         result += ch;
      }  else {
         if (result.size() > subsequence.size()) {
            subsequence = result;
         }
         result = ch;
      }
   }

   if (result.size() > subsequence.size()){
      subsequence = result;
   }

   return subsequence;
}

//code controller
int main() {
   string input = "xyzyy";
   cout << "Input string: " << input << endl;

   string subsequence = longestSubsequence(input);
   cout << "Longest subsequence with different adjacent characters: " << subsequence << endl;

   return 0;
}

Output

Input string: xyzyy
Longest subsequence with different adjacent characters: xyz

Example 2

Implement the problem using dynamic programming. Initialize a 2D array to store the result values and initialize it using memset(). The findLongestSubsequence() function recursively calls calculateSubsequence() to find the longest subsequence with different adjacent characters by storing the non-repetitive neighboring characters.

#include <bits/stdc++.h>
using namespace std;
int dp[100005][27];

string calculateSubsequence(int posl, int pre, const string& str) {   
   if (posl == str.length()) {
      return "";
   }
   if (dp[posl][pre] != -1) {
      return dp[posl][pre] == 1 ? string(1, str[posl]) : "";
   }
   if (str[posl] - 'a' + 1 != pre) {
      string newString = str[posl] + calculateSubsequence(posl + 1, str[posl] - 'a' + 1, str);
      string excludeString = calculateSubsequence(posl + 1, pre, str);
      if (newString.length() > excludeString.length()) { 
         return newString;
      } else {
         return excludeString;
      }
   } else  {
      return calculateSubsequence(posl + 1, pre, str);
   }
}
string findLongestSubsequence(const string& str){
   int l = str.length();
   memset(dp, -1, sizeof(dp));
   return calculateSubsequence(0, 0, str);
}
int main(){   
   string s = "xyzxx";
   string subsequence = findLongestSubsequence(s);
   cout << "Longest subsequence with different adjacent characters: " << subsequence << endl;
   return 0;
}

Output

Longest subsequence with different adjacent characters: xyzx

Conclusion

We have reached the end of this tutorial to find the longest subsequence having different adjacent characters. Adjacent characters are neighboring characters of a character. In this tutorial, we used 2 demonstrations to explain the task requirements of finding the longest subsequence. Used two approaches: the greedy approach and dynamic programming to implement the problem statement of longest subsequence with different adjacent characters in C++.

Dynamic programming reduces the complexity of the problem and does not repeat the same steps multiple times. Instead, it divides tasks into chunks. But it is complex to solve.

The greedy approach is easy to implement and understand but it increases the time complexity of a problem.

Updated on: 03-Oct-2023

98 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements