给定字符串S ,整数K和字符集Q [] ,任务是在字符串S中找到最长的子字符串,该子字符串包含给定字符集Q []中最多K个字符。
例子:
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.
方法:想法是使用两个指针的概念来考虑最大长度的子字符串,以使子字符串最多包含给定集合中的K个字符。下面是该方法的说明:
- 保持左,右为0两个指针,考虑在字符串中这些指针之间。
- 递增右指针,直到给定集合中的字符最多为K。
- 更新最长长度子字符串以使右指针和左指针之间存在差异。
cur_max = max(cur_max, right - left)
- 递增指针向左,并且如果从所述两个指针移出字符是组给定的字符,然后减1的字符的计数从该组。
- 同样,重复上述步骤,直到右指针不等于字符串的长度。
下面是上述方法的实现:
C++
// C++ implementation to find the
// longest substring in the string
// which contains atmost K characters
// from the given set of characters
#include
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 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 decrment 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 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 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 charcter 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 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 charcter which comes out
# then decrment 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
输出:
3
性能分析:
- 时间复杂度: O(N)
- 辅助空间: O(1)