Open In App

Minimum K such that every substring of length atleast K contains a character c

Given a string S containing lowercase latin letters. A character c is called K-amazing if every substring of S with length atleast K contains this character c. Find the minimum possible K such that there exists atleast one K-amazing character.

Examples: 

Input : S = “abcde” 
Output :
Explanation : Every substring of length atleast 3 contains character ‘c’, i.e. 
{“abc”, “bcd”, “cde”, “abcd”, “bcde”, “abcde”} 

Input :S = “aaaa” 
Output :1

Prerequisites : Binary Search

Naive Solution : A simple approach is to iterate over all possible lengths of substrings i.e. from 1 to N (size of string) and for every current length substrings check whether some character appears in all of those substrings.

Efficient Solution : 

The key idea is to perform binary search over the answer K, since if some character c appears in all substrings of length X, it will always appear in all substrings of length (X + 1). Hence, we can check for the current length and try to minimise it using divide and conquer algorithm. For checking if some character appears in all substrings of length X, iterate over all characters from ‘a’ to ‘z’ and inside another loop iteratively store the last occurrence of the last character. 

Let the current position be j, so the last substring of length X will be from (j – X) to X. Check if the position of last occurrence of current K-amazing character is greater than (j – X) or not. If it is greater, then that substring is a valid string.

Below is the implementation of the above approach. 




// CPP Program to find minimum K such that
// every substring of length atleast K
// contains some character c
#include <bits/stdc++.h>
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 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 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# 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
// Php 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
function check($s, $K)
{
    // Iterate over all possible characters
    for ($ch = 0; $ch < 26; $ch++)
    {
        $c = chr(ord('a') + $ch) ;
 
        // stores the last occurrence
        $last = -1;
 
        // set answer as true;
        $found = true;
        for ($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 ($i = $K; $i < strlen($s); $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
function binarySearch($s)
{
    $low = 1 ;
    $high = strlen($s) ;
    while ($low <= $high)
    {
        $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
$s = "abcde";
echo binarySearch($s) . "\n";
 
$s = "aaaa";
echo binarySearch($s) . "\n";
 
// This code is contributed by Ryuga
?>




<script>
 
// Javascript 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
function check(s, K)
{
    // Iterate over all possible characters
    for (var ch = 0; ch < 26; ch++) {
        var c = String.fromCharCode('a'.charCodeAt(0) + ch);
 
        // stores the last occurrence
        var last = -1;
 
        // set answer as true;
        var found = true;
        for (var 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 (var 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
function binarySearch(s)
{
    var low = 1, high = s.length;
    var ans;
    while (low <= high) {
        var 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
var s = "abcde";
document.write( binarySearch(s) + "<br>");
s = "aaaa";
document.write( binarySearch(s) );
 
</script>

Output
3
1

Complexity Analysis:


Article Tags :