📜  给定字符集中最多包含 K 个字符的最长子串

📅  最后修改于: 2021-09-07 02:24:50             🧑  作者: Mango

给定一个字符串S 、一个整数K和字符集Q[] ,任务是从给定的字符集Q[] 中找到最多包含 K 个字符的字符串S 中最长的子字符串。
例子:

方法:想法是使用两个指针的概念来考虑最大长度的子串,使其最多包含给定集合中的 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 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 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 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 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


输出:

3

性能分析:

  • 时间复杂度: O(N)
  • 辅助空间: O(1)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live