📌  相关文章
📜  查找给定字符串具有 k 个唯一字符的最长子字符串

📅  最后修改于: 2021-10-27 07:29:53             🧑  作者: Mango

给定一个字符串,您需要打印可能的最长子字符串,该子字符串恰好包含 M 个唯一字符。如果有多个最长可能长度的子字符串,则打印其中的任何一个。

例子:

"aabbcc", k = 1
Max substring can be any one from {"aa" , "bb" , "cc"}.

"aabbcc", k = 2
Max substring can be any one from {"aabb" , "bbcc"}.

"aabbcc", k = 3
There are substrings with exactly 3 unique characters
{"aabbcc" , "abbcc" , "aabbc" , "abbc" }
Max is "aabbcc" with length 6.

"aaabbb", k = 3
There are only two unique characters, thus show error message. 

资料来源:谷歌面试问题。

方法一(蛮力)
如果字符串的长度为 n,则可以有 n*(n+1)/2 个可能的子字符串。一种简单的方法是生成所有子串并检查每个子串是否恰好有 k 个唯一字符。如果我们应用这种蛮力,则需要 O(n 2 ) 来生成所有子串,并且需要 O(n) 来检查每个子串。因此总体上它会变成 O(n 3 )。
我们可以通过创建哈希表并在生成子字符串时使用该哈希表检查唯一字符的数量来进一步改进此解决方案。因此它将提高到 O(n 2 )。

方法二(线性时间)
这个问题可以用 O(n) 解决。想法是维护一个窗口并向窗口添加元素,直到它包含小于或等于 k ,如果需要,在这样做时更新我们的结果。如果唯一元素超出窗口中的要求,则开始从左侧删除元素。
下面是上面的实现。这些实现假设输入字符串字母表仅包含 26 个字符(从“a”到“z”)。代码可以很容易地扩展到 256 个字符。

C++
// C++ program to find the longest substring with k unique
// characters in a given string
#include 
#include 
#define MAX_CHARS 26
using namespace std;
 
// This function calculates number of unique characters
// using a associative array count[]. Returns true if
// no. of characters are less than required else returns
// false.
bool isValid(int count[], int k)
{
    int val = 0;
    for (int i=0; i 0)
            val++;
 
    // Return true if k is greater than or equal to val
    return (k >= val);
}
 
// Finds the maximum substring with exactly k unique chars
void kUniques(string s, int k)
{
    int u = 0; // number of unique characters
    int n = s.length();
 
    // Associative array to store the count of characters
    int count[MAX_CHARS];
    memset(count, 0, sizeof(count));
 
    // Traverse the string, Fills the associative array
    // count[] and count number of unique characters
    for (int i=0; i max_window_size)
        {
            max_window_size = curr_end-curr_start+1;
            max_window_start = curr_start;
        }
    }
 
    cout << "Max sustring is : "
         << s.substr(max_window_start, max_window_size)
         << " with length " << max_window_size << endl;
}
 
// Driver function
int main()
{
    string s = "aabacbebebe";
    int k = 3;
    kUniques(s, k);
    return 0;
}


Java
import java.util.Arrays;
 
// Java program to find the longest substring with k unique
// characters in a given string
class GFG {
 
    final static int MAX_CHARS = 26;
 
   // This function calculates number
   // of unique characters
   // using a associative array
   // count[]. Returns true if
   // no. of characters are less
   // than required else returns
   // false.
    static boolean isValid(int count[],
                                   int k)
    {
        int val = 0;
        for (int i = 0; i < MAX_CHARS; i++)
        {
            if (count[i] > 0)
            {
                val++;
            }
        }
 
        // Return true if k is greater
        // than or equal to val
        return (k >= val);
    }
 
    // Finds the maximum substring
    // with exactly k unique chars
    static void kUniques(String s, int k)
    {
        int u = 0;
        int n = s.length();
 
        // Associative array to store
        // the count of characters
        int count[] = new int[MAX_CHARS];
        Arrays.fill(count, 0);
        // Traverse the string, Fills
        // the associative array
        // count[] and count number
        // of unique characters
        for (int i = 0; i < n; i++)
        {
            if (count[s.charAt(i) - 'a'] == 0)
            {
                u++;
            }
            count[s.charAt(i) - 'a']++;
        }
 
        // If there are not enough
        // unique characters, show
        // an error message.
        if (u < k) {
            System.out.print("Not enough unique characters");
            return;
        }
 
        // Otherwise take a window with
        // first element in it.
        // start and end variables.
        int curr_start = 0, curr_end = 0;
 
        // Also initialize values for
        // result longest window
        int max_window_size = 1;
        int max_window_start = 0;
 
        // Initialize associative
        // array count[] with zero
        Arrays.fill(count, 0);
         
        // put the first character
        count[s.charAt(0) - 'a']++;
 
        // Start from the second character and add
        // characters in window according to above
        // explanation
        for (int i = 1; i < n; i++) {
            // Add the character 's[i]'
            // to current window
            count[s.charAt(i) - 'a']++;
            curr_end++;
 
            // If there are more than k
            // unique characters in
            // current window, remove from left side
            while (!isValid(count, k)) {
                count[s.charAt(curr_start) - 'a']--;
                curr_start++;
            }
 
            // Update the max window size if required
            if (curr_end - curr_start + 1 > max_window_size)
            {
                max_window_size = curr_end - curr_start + 1;
                max_window_start = curr_start;
            }
        }
 
        System.out.println("Max sustring is : "
                + s.substring(max_window_start,
                    max_window_start + max_window_size)
                + " with length " + max_window_size);
    }
 
    // Driver Code
    static public void main(String[] args) {
        String s = "aabacbebebe";
        int k = 3;
        kUniques(s, k);
    }
}
 
// This code is contributed by 29AjayKumar


Python3
# Python program to find the longest substring with k unique
# characters in a given string
MAX_CHARS = 26
 
# This function calculates number of unique characters
# using a associative array count[]. Returns true if
# no. of characters are less than required else returns
# false.
def isValid(count, k):
    val = 0
    for i in range(MAX_CHARS):
        if count[i] > 0:
            val += 1
 
    # Return true if k is greater than or equal to val
    return (k >= val)
 
# Finds the maximum substring with exactly k unique characters
def kUniques(s, k):
    u = 0 # number of unique characters
    n = len(s)
 
    # Associative array to store the count
    count = [0] * MAX_CHARS
 
    # Tranverse the string, fills the associative array
    # count[] and count number of unique characters
    for i in range(n):
        if count[ord(s[i])-ord('a')] == 0:
            u += 1
        count[ord(s[i])-ord('a')] += 1
 
    # If there are not enough unique characters, show
    # an error message.
    if u < k:
        print ("Not enough unique characters")
        return
 
    # Otherwise take a window with first element in it.
    # start and end variables.
    curr_start = 0
    curr_end = 0
 
    # Also initialize values for result longest window
    max_window_size = 1
    max_window_start = 0
 
    # Initialize associative array count[] with zero
    count = [0] * len(count)
 
    count[ord(s[0])-ord('a')] += 1 # put the first character
 
    # Start from the second character and add
    # characters in window according to above
    # explanation
    for i in range(1,n):
 
        # Add the character 's[i]' to current window
        count[ord(s[i])-ord('a')] += 1
        curr_end+=1
 
        # If there are more than k unique characters in
        # current window, remove from left side
        while not isValid(count, k):
            count[ord(s[curr_start])-ord('a')] -= 1
            curr_start += 1
 
        # Update the max window size if required
        if curr_end-curr_start+1 > max_window_size:
            max_window_size = curr_end-curr_start+1
            max_window_start = curr_start
 
    print ("Max substring is : " + s[max_window_start:max_window_start  + max_window_size]
    + " with length " + str(max_window_size))
 
# Driver function
s = "aabacbebebe"
k = 3
kUniques(s, k)
 
# This code is contributed by BHAVYA JAIN


C#
// C# program to find the longest substring with k unique 
// characters in a given string 
using System;
public class GFG
{
 
  static int MAX_CHARS = 26;
 
  // This function calculates number 
  // of unique characters 
  // using a associative array 
  // count[]. Returns true if 
  // no. of characters are less 
  // than required else returns 
  // false. 
  static bool isValid(int[] count, 
                      int k) 
  { 
    int val = 0; 
    for (int i = 0; i < MAX_CHARS; i++) 
    { 
      if (count[i] > 0) 
      { 
        val++; 
      } 
    } 
 
    // Return true if k is greater
    // than or equal to val 
    return (k >= val); 
  } 
 
  // Finds the maximum substring 
  // with exactly k unique chars 
  static void kUniques(string s, int k) 
  { 
    int u = 0; 
    int n = s.Length; 
 
    // Associative array to store 
    // the count of characters 
    int[] count = new int[MAX_CHARS]; 
    Array.Fill(count, 0);
 
    // Traverse the string, Fills 
    // the associative array 
    // count[] and count number 
    // of unique characters 
    for (int i = 0; i < n; i++) 
    { 
      if (count[s[i] - 'a'] == 0) 
      { 
        u++; 
      } 
      count[s[i] - 'a']++; 
    } 
 
    // If there are not enough 
    // unique characters, show 
    // an error message. 
    if (u < k) { 
      Console.Write("Not enough unique characters"); 
      return; 
    } 
 
    // Otherwise take a window with
    // first element in it. 
    // start and end variables. 
    int curr_start = 0, curr_end = 0; 
 
    // Also initialize values for
    // result longest window 
    int max_window_size = 1;
    int max_window_start = 0; 
 
    // Initialize associative 
    // array count[] with zero 
    Array.Fill(count, 0); 
 
    // put the first character 
    count[s[0] - 'a']++; 
 
    // Start from the second character and add 
    // characters in window according to above 
    // explanation 
    for (int i = 1; i < n; i++)
    {
       
      // Add the character 's[i]' 
      // to current window 
      count[s[i] - 'a']++; 
      curr_end++; 
 
      // If there are more than k 
      // unique characters in 
      // current window, remove from left side 
      while (!isValid(count, k)) { 
        count[s[curr_start] - 'a']--; 
        curr_start++; 
      } 
 
      // Update the max window size if required 
      if (curr_end - curr_start + 1 > max_window_size) 
      { 
        max_window_size = curr_end - curr_start + 1; 
        max_window_start = curr_start; 
      } 
    } 
 
    Console.WriteLine("Max sustring is : "+
                      s.Substring(max_window_start, max_window_size) +
                      " with length " + max_window_size); 
  } 
 
  // Driver code
  static public void Main (){
    string s = "aabacbebebe"; 
    int k = 3; 
    kUniques(s, k); 
  }
}
 
// This code is contributed by avanitrachhadiya2155


Javascript


输出:

Max sustring is : cbebebe with length 7

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程