Longest substring with atmost K characters from the given set of characters
Last Updated :
15 Nov, 2023
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++
// 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 characters
int 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 Code
int 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
// Java implementation to find the
// longest substring in the string
// which contains atmost K characters
// from the given set of characters
import java.util.*;
class GFG{
// Function to find the longest
// substring in the string
// which contains atmost K characters
// from the given set of characters
static 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 code
public 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
# 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 characters
def 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 Code
P = "giraffe"
Q = {chr}
# Construction of set
Q.add('a')
Q.add('f')
Q.add('g')
Q.add('r')
K = 2
N = len(P)
# Output result
print(maxNormalSubstring(P, Q, K, N))
# This code is contributed by Sanjit_Prasad
C#
// C# implementation to find the
// longest substring in the string
// which contains atmost K characters
// from the given set of characters
using System;
using System.Collections.Generic;
// Function to find the longest
// substring in the string
// which contains atmost K characters
// from the given set of characters
class Program {
static int MaxNormalSubstring(string P, HashSet<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;
int 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[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[left - 1])) {
count--;
}
if (count < K) {
break;
}
}
}
return ans;
}
// Driver code
static void Main(string[] args) {
string P = "giraffe";
// Construction of set
HashSet<char> Q = new HashSet<char> { 'a', 'f', 'g', 'r' };
int K = 2;
int N = P.Length;
// Output result
Console.WriteLine(MaxNormalSubstring(P, Q, K, N));
}
}
// This code is contributed by Aman Kumar
JavaScript
<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 characters
function 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 set
Q.add('a')
Q.add('f')
Q.add('g')
Q.add('r')
let K = 2;
let N = P.length;
// output result
document.write(maxNormalSubstring(P, Q, K, N),"</br>");
// This code is contributed by shinjanpatra
</script>
Performance Analysis:
- Time Complexity: O(N)
- Auxiliary Space: O(1)
Similar Reads
Length of the longest substring with consecutive characters Given string str of lowercase alphabets, the task is to find the length of the longest substring of characters in alphabetical order i.e. string "dfabck" will return 3. Note that the alphabetical order here is considered circular i.e. a, b, c, d, e, ..., x, y, z, a, b, c, .... Examples: Input: str =
7 min read
Count of substrings of given string with frequency of each character at most K Given a string str, the task is to calculate the number of substrings of the given string such that the frequency of each element of the string is almost K. Examples: Input: str = "abab", K = 1Output: 7Explanation: The substrings such that the frequency of each character is atmost 1 are "a", "b", "a
6 min read
Longest substring where all the characters appear at least K times | Set 3 Given a string str and an integer K, the task is to find the length of the longest substring S such that every character in S appears at least K times. Examples: Input: str = âaabbbaâ, K = 3Output: 6Explanation: In substring "aabbba", each character repeats at least k times and its length is 6. Inpu
12 min read
Longest substring having all same characters after k changes We have a string of length n, which consist only UPPER English alphabet characters and we have a number k (always less than n and greater than 0). We can make at most k changes in our string such that we can get a longest substring of the same character repeating.Examples: Input : k = 2, s = ABABAOu
15+ min read
String with k distinct characters and no same characters adjacent Given n and k, print a string that has n characters. The string should have exactly k distinct characters and no adjacent positions. Examples: Input : n = 5, k = 3 Output : abcab Explanation: 3 distinct character a, b, c and n length string. Input: 3 2 Output: aba Explanation: 2 distinct character '
6 min read