Longest substring with atmost K characters from the given set of characters
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”, “m”, “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++
#include <bits/stdc++.h>
using namespace std;
int maxNormalSubstring(string& P,
set< char > Q, int K, int N)
{
if (K == 0)
return 0;
int count = 0;
int left = 0, right = 0;
int ans = 0;
while (right < N) {
while (right < N && count <= K) {
if (Q.find(P[right]) != Q.end()){
if (count + 1 > K)
break ;
else
count++;
}
right++;
if (count <= K)
ans = max(ans, right - left);
}
while (left < right) {
left++;
if (Q.find(P[left-1]) != Q.end())
count--;
if (count < K)
break ;
}
}
return ans;
}
int main()
{
string P = "giraffe" ;
set< char > Q;
Q.insert( 'a' );
Q.insert( 'f' );
Q.insert( 'g' );
Q.insert( 'r' );
int K = 2;
int N = P.length();
cout << maxNormalSubstring(P, Q, K, N);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int maxNormalSubstring(String P,
Set<Character> Q,
int K, int N)
{
if (K == 0 )
return 0 ;
int count = 0 ;
int left = 0 , right = 0 ;
int ans = 0 ;
while (right < N)
{
while (right < N && count <= K)
{
if (Q.contains(P.charAt(right)))
{
if (count + 1 > K)
break ;
else
count++;
}
right++;
if (count <= K)
ans = Math.max(ans, right - left);
}
while (left < right)
{
left++;
if (Q.contains(P.charAt(left- 1 )))
count--;
if (count < K)
break ;
}
}
return ans;
}
public static void main(String[] args)
{
String P = "giraffe" ;
Set<Character> Q = new HashSet<>();
Q.add( 'a' );
Q.add( 'f' );
Q.add( 'g' );
Q.add( 'r' );
int K = 2 ;
int N = P.length();
System.out.println(maxNormalSubstring(P, Q,
K, N));
}
}
|
Python3
def maxNormalSubstring(P, Q, K, N):
if (K = = 0 ):
return 0
count = 0
left = 0
right = 0
ans = 0
while (right < N):
while (right < N and count < = K):
if (P[right] in Q):
if (count + 1 > K):
break
else :
count + = 1
right + = 1
if (count < = K):
ans = max (ans, right - left)
while (left < right):
left + = 1
if (P[left - 1 ] in Q):
count - = 1
if (count < K):
break
return ans
P = "giraffe"
Q = { chr }
Q.add( 'a' )
Q.add( 'f' )
Q.add( 'g' )
Q.add( 'r' )
K = 2
N = len (P)
print (maxNormalSubstring(P, Q, K, N))
|
C#
using System;
using System.Collections.Generic;
class Program {
static int MaxNormalSubstring( string P, HashSet< char > Q, int K, int N) {
if (K == 0) {
return 0;
}
int count = 0;
int left = 0;
int right = 0;
int ans = 0;
while (right < N) {
while (right < N && count <= K) {
if (Q.Contains(P[right])) {
if (count + 1 > K) {
break ;
} else {
count++;
}
}
right++;
if (count <= K) {
ans = Math.Max(ans, right - left);
}
}
while (left < right) {
left++;
if (Q.Contains(P[left - 1])) {
count--;
}
if (count < K) {
break ;
}
}
}
return ans;
}
static void Main( string [] args) {
string P = "giraffe" ;
HashSet< char > Q = new HashSet< char > { 'a' , 'f' , 'g' , 'r' };
int K = 2;
int N = P.Length;
Console.WriteLine(MaxNormalSubstring(P, Q, K, N));
}
}
|
Javascript
<script>
function maxNormalSubstring(P, Q, K, N)
{
if (K == 0)
return 0;
let count = 0;
let left = 0, right = 0;
let ans = 0;
while (right < N) {
while (right < N && count <= K) {
if (Q.has(P[right])){
if (count + 1 > K)
break ;
else
count++;
}
right++;
if (count <= K)
ans = Math.max(ans, right - left);
}
while (left < right) {
left++;
if (Q.has(P[left-1]))
count--;
if (count < K)
break ;
}
}
return ans;
}
let P = "giraffe"
let Q = new Set()
Q.add( 'a' )
Q.add( 'f' )
Q.add( 'g' )
Q.add( 'r' )
let K = 2;
let N = P.length;
document.write(maxNormalSubstring(P, Q, K, N), "</br>" );
</script>
|
Performance Analysis:
- Time Complexity: O(N)
- Auxiliary Space: O(1)
Last Updated :
15 Nov, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...