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

📅  最后修改于: 2021-09-16 10:51:44             🧑  作者: Mango

给定一个包含小写拉丁字母的字符串S。如果长度为ATLEASTķS的每个子字符串包含此字符c字符C被称为K-惊人。找到最小可能的 K,使得至少存在一个 K-amazing字符。
例子:

先决条件:二分搜索
天真的解决方案:一个简单的方法是迭代所有可能的子字符串长度,即从 1 到 N(字符串的大小),并为每个当前长度的子字符串检查是否某个字符出现在所有这些子字符串中。
有效的解决方案:关键思想是对答案K执行二分搜索,因为如果某个字符c 出现在长度为X 的所有子字符串中,那么它将始终出现在长度为(X + 1) 的所有子字符串中。因此,我们可以检查当前长度并尝试使用分治算法将其最小化。为了检查某个字符出现在所有长度为 X 的子字符串中,迭代从 ‘a’ 到 ‘z’ 的所有字符,并在另一个循环中迭代地存储最后一个字符的最后一次出现。
设当前位置为j,所以最后一个长度为X的子串是从(j-X)到X。检查当前K-amazing字符最后出现的位置是否大于(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
?>


Javascript


输出:

3
1

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

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