📌  相关文章
📜  所有字符至少出现K次的最大子字符串|套装2

📅  最后修改于: 2021-05-08 17:52:01             🧑  作者: Mango

给定一个字符串str和一个整数K,任务是找到最长的子字符串的长度S,使得S中的每一个字符出现至少K倍。

例子:

朴素的方法:我们在上一篇文章中讨论了朴素的方法。

方法:在本文中,我们将讨论使用分而治之技术和递归的方法。步骤如下:

  1. 将给定字符串的每个字符的频率存储在大小为26的频率数组中。
  2. 初始化两个变量0开始结束,其是字符串str的长度。
  3. 遍历从开始字符串结束和计数的时间的每个字符重复数,并将其存储在数组中。
  4. 如果任何字符重复的次数少于K次,则将字符串分成两半。如果i是我们发现的字符串[I]K次重复少,那么我们把字符串转换成从开始两ii + 1,结束字符串的索引。
  5. 在上述步骤中递归调用两个半部分,即从开始到ii + 1分别结束,然后重复步骤2和3,并通过上述递归调用返回两个值reutnr的最大值。
  6. 如果开始结束之间的所有字符都重复了至少K次,则答案为end – start

    下面是上述方法的实现:

    C++
    // C++ program for the above approach 
    #include  
    using namespace std; 
      
    // Function to find the longest substring 
    int longestSubstring(int start, int end, 
                        string s, int k) 
    { 
        int left, right; 
      
        // Array for counting the number of 
        // times each character repeats 
        // count the number of times each 
        // character repeats from start to end 
        int count[26] = { 0 }; 
      
        // Store the frequency from s[start...end] 
        for (int i = start; i < end; i++) { 
            count[s[i] - 'a'] += 1; 
        } 
      
        // Iterate from [start, end] 
        for (int i = start; i < end; i++) { 
      
            if (count[s[i] - 'a'] < k) { 
      
                // Recursive call for left subpart 
                left = longestSubstring(start, 
                                        i, 
                                        s, 
                                        k); 
      
                // Recursive call for right subpart 
                right = longestSubstring(i + 1, 
                                        end, 
                                        s, 
                                        k); 
      
                // Return maximum of left & right 
                return max(left, right); 
            } 
        } 
      
        // If all the characters are repeated 
        // at least k times 
        return end - start; 
    } 
      
    // Driver Code 
    int main() 
    { 
        // Given String str 
        string str = "aabbba"; 
        int k = 3; 
      
        // Function Call 
        cout << longestSubstring(0, str.length(), 
                                str, k) 
            << endl; 
        return 0; 
    }


    Java
    // Java program for the above approach 
    import java.util.*; 
      
    class GFG{ 
      
    // Function to find the longest subString 
    static int longestSubString(int start, int end, 
                                String s, int k) 
    { 
        int left, right; 
      
        // Array for counting the number of 
        // times each character repeats 
        // count the number of times each 
        // character repeats from start to end 
        int count[] = new int[26]; 
      
        // Store the frequency from s[start...end] 
        for(int i = start; i < end; i++) 
        { 
            count[s.charAt(i) - 'a'] += 1; 
        } 
      
        // Iterate from [start, end] 
        for(int i = start; i < end; i++) 
        { 
            if (count[s.charAt(i) - 'a'] < k) 
            { 
                  
                // Recursive call for left subpart 
                left = longestSubString(start, i, 
                                        s, k); 
      
                // Recursive call for right subpart 
                right = longestSubString(i + 1, end, 
                                        s, k); 
      
                // Return maximum of left & right 
                return Math.max(left, right); 
            } 
        } 
      
        // If all the characters are repeated 
        // at least k times 
        return end - start; 
    } 
      
    // Driver Code 
    public static void main(String[] args) 
    { 
      
        // Given String str 
        String str = "aabbba"; 
        int k = 3; 
      
        // Function Call 
        System.out.print(longestSubString(0, str.length(), 
                                            str, k) + "\n"); 
    } 
    } 
      
    // This code is contributed by Amit Katiyar


    Python3
    # Python3 program for the above approach 
      
    # Function to find the longest substring 
    def longestSubString(start, end, s, k): 
          
        # List for counting the number of 
        # times each character repeats 
        # count the number of times each 
        # chracter repeats from start to end 
        count = [0 for i in range(26)] 
          
        # Store the frequency from s[start...end] 
        for i in range(start, end): 
            count[ord(s[i]) - ord('a')] += 1
          
        # Iterate from [start, end] 
        for i in range(start, end): 
            if(count[ ord(s[i]) - ord('a')] < k): 
                  
                # Recursive call for left subpart 
                left = longestSubString(start, i, 
                                            s, k) 
                                          
                # Recursive call for right subpart 
                right = longestSubString(i + 1, end, 
                                            s, k) 
                                          
                # Return maximum of left & right 
                return max(left, right) 
          
        # If all the characters are repeated 
        # at least k times 
        return end - start 
          
    # Driver Code 
      
    # Given String str 
    str = "aabbba"
    k = 3
      
    # Function call 
    print(longestSubString(0, len(str), str, k)) 
      
    # This code is contributed by dadimadhav


    C#
    // C# program for the above approach
    using System;
      
    class GFG{
      
    // Function to find the longest subString
    static int longestSubString(int start, int end,
                                 string s, int k)
    {
        int left, right;
      
        // Array for counting the number of
        // times each character repeats
        // count the number of times each
        // character repeats from start to end
        int []count = new int[26];
      
        // Store the frequency from s[start...end]
        for(int i = start; i < end; i++)
        {
            count[s[i] - 'a'] += 1;
        }
      
        // Iterate from [start, end]
        for(int i = start; i < end; i++)
        {
            if (count[s[i] - 'a'] < k) 
            {
                  
                // Recursive call for left subpart
                left = longestSubString(start, i,
                                        s, k);
      
                // Recursive call for right subpart
                right = longestSubString(i + 1, end,
                                         s, k);
      
                // Return maximum of left & right
                return Math.Max(left, right);
            }
        }
      
        // If all the characters are repeated
        // at least k times
        return end - start;
    }
      
    // Driver Code
    public static void Main(string[] args)
    {
          
        // Given String str
        string str = "aabbba";
        int k = 3;
      
        // Function call
        Console.Write(longestSubString(0, str.Length,
                                          str, k) + "\n");
    }
    }
      
    // This code is contributed by rutvik_56


    输出:
    6
    

    时间复杂度: O(N * log 2 N)