Longest substring with atmost K characters from the given set of characters - GeeksforGeeks

10 May, 2022
Given a string S, an integer K and set of characters Q[], the task is to find the longest substring in string S which contains atmost K characters from the given character set Q[].Examples:  
Input: S = “normal”, Q = {“a”, “o”, “n”, “b”, “r”, “l”}, K = 1 Output: 1 Explanation: All the characters in the given string S are present in array. Therefore, we can select any substring of length 1.Input: S = “giraffe”, Q = {“a”, “f”, “g”, “r”}, K = 2 Output : 3 Explanation: Possible substrings with atmost 2 characters From the given set are {“gir”, “ira”, “ffe”} The maximum length of all the substrings is 3.  
Approach: The idea is to use the concept of two pointers to consider the substrings of maximum length, such that it contains at most K character from the given set. Below is the illustration of the approach: 
Maintain two pointers left and right as 0, to consider the string in between these pointers.
Increment the right pointer until the characters from the given set is at most K.
Update the longest length substring to be difference between the right pointer and left pointer.  
cur_max = max(cur_max, right - left)
Increment the left pointer and if the character which moved out from the two pointers is the character of the given set, then decrement the count of the characters from the set by 1.
Similarly, repeat the steps above until the right pointer is not equal to the length of the string.
Below is the implementation of the above approach: 
C++
Java
Python3
Javascript
// C++ implementation to find the// longest substring in the string// which contains atmost K characters// from the given set of characters #include <bits/stdc++.h> using namespace std; // Function to find the longest// substring in the string// which contains atmost K characters// from the given set of charactersint maxNormalSubstring(string& P,        set<char> Q, int K, int N){     // Base Condition    if (K == 0)        return 0;     // Count for Characters    // from set in substring    int count = 0;         // Two pointers    int left = 0, right = 0;    int ans = 0;     // Loop to iterate until    // right pointer is not    // equal to N    while (right < N) {                 // Loop to increase the substring        // length until the characters from        // set are at most K        while (right < N && count <= K) {             // Check if current pointer            // points a character from set            if (Q.find(P[right]) != Q.end()){                                 // If the count of the                // char is exceeding the limit                if (count + 1 > K)                    break;                else                    count++;            }             right++;             // update answer with            // substring length            if (count <= K)                ans = max(ans, right - left);        }                 // Increment the left pointer until        // the count is less than or equal to K        while (left < right) {            left++;                         // If the character which comes out is normal character            // then decrement the count by 1            if (Q.find(P[left-1]) != Q.end())                count--;             if (count < K)                break;        }    }     return ans;} // Driver Codeint main(){    string P = "giraffe";    set<char> Q;         // Construction of set    Q.insert('a');    Q.insert('f');    Q.insert('g');    Q.insert('r');    int K = 2;    int N = P.length();     // output result    cout << maxNormalSubstring(P, Q, K, N);     return 0;}
// Java implementation to find the// longest substring in the string// which contains atmost K characters// from the given set of charactersimport java.util.*; class GFG{     // Function to find the longest// substring in the string// which contains atmost K characters// from the given set of charactersstatic int maxNormalSubstring(String P,                              Set<Character> Q,                              int K, int N){         // Base Condition    if (K == 0)        return 0;     // Count for Characters    // from set in substring    int count = 0;     // Two pointers    int left = 0, right = 0;    int ans = 0;     // Loop to iterate until    // right pointer is not    // equal to N    while (right < N)    {         // Loop to increase the substring        // length until the characters from        // set are at most K        while (right < N && count <= K)        {             // Check if current pointer            // points a character from set            if (Q.contains(P.charAt(right)))            {                                 // If the count of the                // char is exceeding the limit                if (count + 1 > K)                    break;                else                    count++;            }            right++;             // update answer with            // substring length            if (count <= K)                ans = Math.max(ans, right - left);        }         // Increment the left pointer until        // the count is less than or equal to K        while (left < right)        {            left++;             // If the character which comes out            // then decrement the count by 1            if (Q.contains(P.charAt(left-1)))                count--;            if (count < K)                break;        }    }    return ans;} // Driver codepublic static void main(String[] args){    String P = "giraffe";    Set<Character> Q = new HashSet<>();     // Construction of set    Q.add('a');    Q.add('f');    Q.add('g');    Q.add('r');         int K = 2;    int N = P.length();     // Output result    System.out.println(maxNormalSubstring(P, Q,                                          K, N));}} // This code is contributed by offbeat
# Python3 implementation to find the# longest substring in the string# which contains atmost K characters# from the given set of characters # Function to find the longest# substring in the string# which contains atmost K characters# from the given set of charactersdef maxNormalSubstring(P, Q, K, N):     # Base Condition    if (K == 0):        return 0     # Count for Characters    # from set in substring    count = 0         # Two pointers    left = 0    right = 0    ans = 0     # Loop to iterate until    # right pointer is not    # equal to N    while (right < N):                 # Loop to increase the substring        # length until the characters from        # set are at most K        while (right < N and count <= K):             # Check if current pointer            # points a character from set            if (P[right] in Q):                                 # If the count of the                # char is exceeding the limit                if (count + 1 > K):                    break                else:                    count += 1             right += 1             # update answer with            # substring length            if (count <= K):                ans = max(ans, right - left)                 # Increment the left pointer until        # the count is less than or equal to K        while (left < right):            left += 1                         # If the character which comes out            # then decrement the count by 1            if (P[left-1] in Q):                count -= 1             if (count < K):                break     return ans # Driver CodeP = "giraffe"Q = {chr} # Construction of setQ.add('a')Q.add('f')Q.add('g')Q.add('r')K = 2N = len(P) # Output resultprint(maxNormalSubstring(P, Q, K, N)) # This code is contributed by Sanjit_Prasad
<script> // JavaScript implementation of above approach // Function to find the longest// substring in the string// which contains atmost K characters// from the given set of charactersfunction maxNormalSubstring(P, Q, K, N){     // Base Condition    if (K == 0)        return 0;     // Count for Characters    // from set in substring    let count = 0;         // Two pointers    let left = 0, right = 0;    let ans = 0;     // Loop to iterate until    // right pointer is not    // equal to N    while (right < N) {                 // Loop to increase the substring        // length until the characters from        // set are at most K        while (right < N && count <= K) {             // Check if current pointer            // points a character from set            if (Q.has(P[right])){                                 // If the count of the                // char is exceeding the limit                if (count + 1 > K)                    break;                else                    count++;            }             right++;             // update answer with            // substring length            if (count <= K)                ans = Math.max(ans, right - left);        }                 // Increment the left pointer until        // the count is less than or equal to K        while (left < right) {            left++;                         // If the character which comes out is normal character            // then decrement the count by 1            if (Q.has(P[left-1]))                count--;             if (count < K)                break;        }    }     return ans;} // Driver Code let P = "giraffe"let Q = new Set() // Construction of setQ.add('a')Q.add('f')Q.add('g')Q.add('r')let K = 2;let N = P.length; // output resultdocument.write(maxNormalSubstring(P, Q, K, N),"</br>"); // This code is contributed by shinjanpatra </script>
3
 
Performance Analysis:  
Time Complexity: O(N)
Auxiliary Space: O(1)
Sanjit_Prasad
offbeat
nidhi_biet
NikhilReddyKonda
surinderdawra388
shinjanpatra
substring
Greedy
Pattern Searching
Strings
Strings
Greedy
Pattern Searching
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Optimal Page Replacement Algorithm
Program for Best Fit algorithm in Memory Management
Program for First Fit algorithm in Memory Management
Bin Packing Problem (Minimize number of used Bins)
Max Flow Problem Introduction
KMP Algorithm for Pattern Searching
Rabin-Karp Algorithm for Pattern Searching
Check if a string is substring of another
Naive algorithm for Pattern Searching
Boyer Moore Algorithm for Pattern Searching