📌  相关文章
📜  最小K,以使每个长度至少为K的子字符串都包含一个字符c

📅  最后修改于: 2021-05-06 21:02:58             🧑  作者: Mango

给定一个包含小写拉丁字母的字符串S。如果S的每个长度至少为K的子字符串包含此字符c,则将字符c称为K-amazing。求出最小可能的K,使得存在至少一个K令人惊奇的字符。

例子:

先决条件:二进制搜索

天真的解决方案:一种简单的方法是遍历子字符串的所有可能的长度,即从1到N(字符串的大小),并针对每个当前长度的子字符串检查是否在所有这些子字符串中都出现了某个字符。

高效的解决方案:关键思想是对答案K进行二进制搜索,因为如果某个字符c出现在所有长度为X的子字符串中,它将始终出现在所有长度为(X + 1)的子字符串中。因此,我们可以检查当前长度,并尝试使用分而治之算法将其最小化。为了检查某个字符出现在长度为X的所有子字符串中,请从’a’到’z’遍历所有字符,并在另一个循环内迭代地存储最后一个字符的最后一次出现。
假设当前位置为j,则长度X的最后一个子串将从(j – X)到X。检查当前出现的当前K令人惊奇的字符是否大于(j – X)。如果更大,则该子字符串是有效的字符串。

下面是上述方法的实现。

C++
// CPP Program to find minimum K such that
// every substring of length atleast K
// contains some character c
#include 
using namespace std;
  
// This function checks if there exists some
// character which appears in all K length
// substrings
int check(string s, int K)
{
    // Iterate over all possible characters
    for (int ch = 0; ch < 26; ch++) {
        char c = 'a' + ch;
  
        // stores the last occurrence
        int last = -1;
  
        // set answer as true;
        bool found = true;
        for (int i = 0; i < K; i++)
            if (s[i] == c)
                last = i;
  
        // No occurrence found of current
        // character in first substring
        // of length K
        if (last == -1)
            continue;
  
        // Check for every last substring
        // of length K where last occurr-
        // ence exists in substring
        for (int i = K; i < s.size(); i++) {
            if (s[i] == c)
                last = i;
  
            // If last occ is not
            // present in substring
            if (last <= (i - K)) {
                found = false;
                break;
            }
        }
        // current character is K amazing
        if (found)
            return 1;
    }
    return 0;
}
  
// This function performs binary search over the
// answer to minimise it
int binarySearch(string s)
{
    int low = 1, high = (int)s.size();
    int ans;
    while (low <= high) {
        int mid = (high + low) >> 1;
  
        // Check if answer is found try
        // to minimise it
        if (check(s, mid)) {
            ans = mid;
            high = mid - 1;
        }
        else
            low = mid + 1;
    }
    return ans;
}
  
// Driver Code to test above functions
int32_t main()
{
    string s = "abcde";
    cout << binarySearch(s) << endl;
  
    s = "aaaa";
    cout << binarySearch(s) << endl;
    return 0;
}


Java
// Java Program to find minimum K such that
// every substring of length atleast K
// contains some character c
  
class GFG
{
      
          
        // This function checks if there exists some
        // character which appears in all K length
        // substrings
        static int check(String s, int K)
        {
            // Iterate over all possible characters
            for (int ch = 0; ch < 26; ch++) {
                char c = (char)( 'a' + ch);
          
                // stores the last occurrence
                int last = -1;
          
                // set answer as true;
                boolean found = true;
                for (int i = 0; i < K; i++)
                    if (s.charAt(i) == c)
                        last = i;
          
                // No occurrence found of current
                // character in first substring
                // of length K
                if (last == -1)
                    continue;
          
                // Check for every last substring
                // of length K where last occurr-
                // ence exists in substring
                for (int i = K; i < s.length(); i++) {
                    if (s.charAt(i) == c)
                        last = i;
          
                    // If last occ is not
                    // present in substring
                    if (last <= (i - K)) {
                        found = false;
                        break;
                    }
                }
                // current character is K amazing
                if (found)
                    return 1;
            }
            return 0;
        }
          
        // This function performs binary search over the
        // answer to minimise it
        static int binarySearch(String s)
        {
            int low = 1, high = s.length();
            int ans=0;
            while (low <= high) {
                int mid = (high + low) >> 1;
          
                // Check if answer is found try
                // to minimise it
                if (check(s, mid)==1) {
                    ans = mid;
                    high = mid - 1;
                }
                else
                    low = mid + 1;
            }
            return ans;
        }
          
        // Driver Code to test above functions
        public static void main(String args[])
        {
            String s = "abcde";
            System.out.println(binarySearch(s));
          
            s = "aaaa";
            System.out.println(binarySearch(s));
      
        }
  
}
  
// This article is contributed 
// by ihritik


Python3
# Python3 Program to find minimum K such 
# that every substring of length atleast 
# K contains some character c 
  
# This function checks if there exists 
# some character which appears in all 
# K length substrings 
def check(s, K): 
  
    # Iterate over all possible characters 
    for ch in range(0, 26): 
        c = chr(97 + ch) # Ascii value of 'a' => 97
  
        # stores the last occurrence 
        last = -1
  
        # set answer as true 
        found = True
        for i in range(0, K): 
            if s[i] == c: 
                last = i 
  
        # No occurrence found of current character 
        # in first substring of length K 
        if last == -1: 
            continue
  
        # Check for every last substring 
        # of length K where last occurr- 
        # ence exists in substring 
        for i in range(K, len(s)):
            if s[i] == c: 
                last = i 
  
            # If last occ is not 
            # present in substring 
            if last <= (i - K): 
                found = False
                break
              
        # current character is K amazing 
        if found: 
            return 1
      
    return 0
  
# This function performs binary search 
# over the answer to minimise it 
def binarySearch(s): 
  
    low, high, ans = 1, len(s), None
      
    while low <= high: 
        mid = (high + low) >> 1
  
        # Check if answer is found 
        # try to minimise it 
        if check(s, mid): 
            ans, high = mid, mid - 1
          
        else:
            low = mid + 1
      
    return ans 
  
# Driver Code
if __name__ == "__main__": 
  
    s = "abcde"
    print(binarySearch(s)) 
  
    s = "aaaa"
    print(binarySearch(s)) 
  
# This code is contributed by Rituraj Jain


C#
// C# Program to find minimum K such that
// every substring of length atleast K
// contains some character c
  
using System;
class GFG
{
      
          
        // This function checks if there exists some
        // character which appears in all K length
        // substrings
        static int check(String s, int K)
        {
            // Iterate over all possible characters
            for (int ch = 0; ch < 26; ch++) {
                char c = (char)( 'a' + ch);
          
                // stores the last occurrence
                int last = -1;
          
                // set answer as true;
                bool found = true;
                for (int i = 0; i < K; i++)
                    if (s[i] == c)
                        last = i;
          
                // No occurrence found of current
                // character in first substring
                // of length K
                if (last == -1)
                    continue;
          
                // Check for every last substring
                // of length K where last occurr-
                // ence exists in substring
                for (int i = K; i < s.Length; i++) {
                    if (s[i] == c)
                        last = i;
          
                    // If last occ is not
                    // present in substring
                    if (last <= (i - K)) {
                        found = false;
                        break;
                    }
                }
                // current character is K amazing
                if (found)
                    return 1;
            }
            return 0;
        }
          
        // This function performs binary search over the
        // answer to minimise it
        static int binarySearch(String s)
        {
            int low = 1, high = s.Length;
            int ans=0;
            while (low <= high) {
                int mid = (high + low) >> 1;
          
                // Check if answer is found try
                // to minimise it
                if (check(s, mid)==1) {
                    ans = mid;
                    high = mid - 1;
                }
                else
                    low = mid + 1;
            }
            return ans;
        }
          
        // Driver Code to test above functions
        public static void Main()
        {
            String s = "abcde";
            Console.WriteLine(binarySearch(s));
          
            s = "aaaa";
            Console.WriteLine(binarySearch(s));
      
        }
  
}
  
// This article is contributed 
// by ihritik


PHP
> 1; 
  
        // Check if answer is found try 
        // to minimise it 
        if (check($s, $mid))
        { 
            $ans = $mid; 
            $high = $mid - 1; 
        } 
        else
            $low = $mid + 1; 
    } 
    return $ans; 
} 
  
// Driver Code
$s = "abcde"; 
echo binarySearch($s) . "\n";
  
$s = "aaaa"; 
echo binarySearch($s) . "\n"; 
  
// This code is contributed by Ryuga
?>


输出:
3
1

时间复杂度: O(N * logN * 26),其中N是给定字符串的大小。