
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Longest Subsequence with Same Char as Substrings and Frequency Difference at Most K
In this problem, we will find the maximum length of the subsequence such that it should contain the contiguous characters, and the frequency difference of all characters won't differ more than K.
We need to find all possible subsequences of the given string and check whether it contains every character continuously and maximum frequency difference to get the output.
Problem statement? We have given a string alpha containing the lowercase alphabetical characters. Also, we have given the positive integer K. We need to find the maximum length of the subsequence of the given string such that it follows the below rules.
All occurrences of the particular character should be contiguous.
The difference of frequency of characters should not be more than K.
Sample examples
Input
alpha = "ppppqrs", K = 2
Output
6
Explanation ? We can take the ?pppqrs' subsequence. The maximum character frequency is 3, and the minimum character frequency is 1. So, the difference is 2. Also, it contains all characters continuously.
Input
alpha = "abbbbc", K = 2
Output
5
Explanation ? We can take the ?abbbc' subsequence.
Input
alpha = "mnnnnnnno", k = 3;
Output
7
Explanation ? We can take the ?nnnnnnn' subsequence.
Approach 1
In this approach, we will use the recursive function to find all subsequences of the given length. Also, we will define the function to check whether the subsequence contains all characters continuously. We will use the map data structure to count the maximum and minimum frequency differences.
Algorithm
Step 1 ? Define the ?f' map to store the frequency of characters.
Step 2 ? If the start is equal to the temp string's length, and the string length is greater than 0, follow the steps below.
Step 3 ? Initialize the ?minf' and ?maxf' variables to store the minimum and maximum frequency.
Step 4 ? Clear the map, and store each character's frequency in the map.
Step 5 ? Traverse the map values and find the maximum and minimum frequency values.
Step 6 ? If the maximum and minimum frequency difference is less than or equal to K, check whether the string contains continuous characters.
Step 6.1 ? In the checkForContinuous() function, define the ?pos' map to store the last position of the particular character.
Step 6.2 ? Traverse the string. If Current characters exist in the map, and the difference between the current position and the last position of the character is less than 1, update the last position. Otherwise, return false.
Step 6.3 ? Add a character to the map if the character doesn't exist.
Step 6.4 ? Return true at the end.
Step 7 ? If the string contains the continuous character, and the frequency difference is less than K, update the value of the ?maxi' if it is less than the current subsequence's length.
Step 8 ? Make a recursive call after excluding the current character.
Step 9 ? Append the current character at the end of the temp string. Also, make a recursive call with the updated ?tmp' string.
Example
#include <bits/stdc++.h> using namespace std; int maxi = 0; // Check for continuous characters in the substring bool CheckForContinuous(string &tmp) { // map to store the last index of the character unordered_map<char, int> pos; for (int p = 0; p < tmp.length(); p++) { // When the last index exists in the map if (pos[tmp[p]]) { // If the last index is adjacent to the current index if (p - pos[tmp[p]] + 1 <= 1) pos[tmp[p]] = p + 1; else return false; } else { // When the map doesn't have a character as a key pos[tmp[p]] = p + 1; } } return true; } void getLongestSubSeq(string &alpha, string tmp, int start, int &k) { // To store the character's frequency unordered_map<char, int> f; if (start == alpha.length()) { if (tmp.length() > 0) { // To store minimum and maximum frequency of characters int minf = INT_MAX, maxf = INT_MIN; // Make map empty f.clear(); // Store frequency of characters in the map for (int p = 0; p < tmp.length(); p++) f[tmp[p]]++; // Get minimum and maximum value from the map for (auto &key : f) { minf = min(minf, key.second); maxf = max(maxf, key.second); } // Validate substring for frequency difference and continuous characters if (maxf - minf <= k && CheckForContinuous(tmp)) maxi = max(maxi, (int)tmp.length()); } return; } // Exclude current character getLongestSubSeq(alpha, tmp, start + 1, k); // Include current character tmp.push_back(alpha[start]); getLongestSubSeq(alpha, tmp, start + 1, k); } int main() { string alpha = "ppppqrs", tmp; int k = 2; getLongestSubSeq(alpha, tmp, 0, k); cout <<"The maximum length of the substring according to the given conditions is " << maxi; return 0; }
Output
The maximum length of the substring according to the given conditions is 6
Time complexity ? O(N*2N), where O(N) is to check for contiguous characters, and O(2N) for finding all subsequences.
Space complexity ? O(N) to store the temporary subsequence.
We used the naïve approach to find all subsequences of the given string. However, it is very time expensive. Using this approach for large strings is not recommended to solve the problem.