📌  相关文章
📜  最小化包含至少一个公共字符的子字符串的长度

📅  最后修改于: 2021-04-21 23:34:14             🧑  作者: Mango

给定一个字符串str ,任务是找到子字符串的最小长度,以使str中具有该长度的所有子字符串都至少包含一个公共字符。如果无法获得这样的长度,请打印-1
例子:

方法:使用二进制搜索技术可以轻松解决此问题。请按照以下步骤解决问题:

  • 初始化1为字符串str的长度。
  • 在高低之间找到中间
  • 如果给定字符串的所有子字符串中都有一个公共字符,则将其更新为-1。
  • 如果不是这种情况,则将Low更新为mid + 1
  • 字母表中的所有26个可能的字符重复上述步骤。

下面是上述方法的实现:

C++
// C++ Program to implement
// the above approach
#include 
using namespace std;
  
// Function to check and return if
// substrings of length mid has a
// common character a
bool check(string& str, int mid, char a)
{
  
    // Length of the string
    int n = str.size();
  
    // Initialise the first
    // occurrence of character a
    int previous = -1, i;
  
    for (i = 0; i < n; ++i) {
  
        if (str[i] == a) {
  
            // Check that distance b/w
            // the current and previous
            // occurrence of character a
            // is less than or equal to mid
            if (i - previous > mid) {
                return false;
            }
            previous = i;
        }
    }
  
    // If distance exceeds mid
    if (i - previous > mid)
        return false;
    else
        return true;
}
  
// Function to check for all the
// alphabets, if substrings of
// length mid have a character common
bool possible(string& str, int mid)
{
  
    // Check for all 26 alphabets
    for (int i = 0; i < 26; ++i) {
  
        // Check that char i + a is
        // common in all the substrings
        // of length mid
        
        if (check(str, mid, i + 'a'))
            return true;
    }
  
    // If no characters is common
    return false;
}
  
// Function to calculate and return
// the minm length of substrings
int findMinLength(string& str)
{
  
    // Initialise low and high
    int low = 1, high = str.length();
  
    // Perform binary search
    while (low <= high) {
  
        // Update mid
        int mid = (low + high) / 2;
  
        // Check if one common character is
        // present in the length of the mid
        if (possible(str, mid))
            high = mid - 1;
        else
            low = mid + 1;
    }
  
    // Returns the minimum length
    // that contain one
    // common character
    return high + 1;
}
  
// Function to check if all
// characters are distinct
bool ifAllDistinct(string str)
{
    set s;
    for (char c : str) {
        s.insert(c);
    }
  
    return s.size() == str.size();
}
  
// Driver Code
int main()
{
  
    string str = "geeksforgeeks";
  
    if (ifAllDistinct(str))
        cout << -1 << endl;
    else
        cout << findMinLength(str);
    return 0;
}


Java
// Java program to implement
// the above approach
import java.util.*;
  
class GFG{
  
// Function to check and return if
// subStrings of length mid has a
// common character a
static boolean check(char[] str, int mid, 
                     char a)
{
  
    // Length of the String
    int n = str.length;
  
    // Initialise the first
    // occurrence of character a
    int previous = -1, i;
  
    for(i = 0; i < n; ++i) 
    {
        if (str[i] == a) 
        {
  
            // Check that distance b/w
            // the current and previous
            // occurrence of character a
            // is less than or equal to mid
            if (i - previous > mid)
            {
                return false;
            }
            previous = i;
        }
    }
  
    // If distance exceeds mid
    if (i - previous > mid)
        return false;
    else
        return true;
}
  
// Function to check for all the
// alphabets, if subStrings of
// length mid have a character common
static boolean possible(char[] str, int mid)
{
  
    // Check for all 26 alphabets
    for(int i = 0; i < 26; ++i) 
    {
          
        // Check that char i + a is
        // common in all the subStrings
        // of length mid
        if (check(str, mid, (char)(i + 'a')))
            return true;
    }
  
    // If no characters is common
    return false;
}
  
// Function to calculate and return
// the minm length of subStrings
static int findMinLength(char[] str)
{
  
    // Initialise low and high
    int low = 1, high = str.length;
  
    // Perform binary search
    while (low <= high)
    {
          
        // Update mid
        int mid = (low + high) / 2;
  
        // Check if one common character is
        // present in the length of the mid
        if (possible(str, mid))
            high = mid - 1;
        else
            low = mid + 1;
    }
  
    // Returns the minimum length
    // that contain one
    // common character
    return high + 1;
}
  
// Function to check if all
// characters are distinct
static boolean ifAllDistinct(String str)
{
    HashSet s = new HashSet();
    for(char c : str.toCharArray())
    {
        s.add(c);
    }
    return s.size() == str.length();
}
  
// Driver Code
public static void main(String[] args)
{
    String str = "geeksforgeeks";
  
    if (ifAllDistinct(str))
        System.out.print(-1 + "\n");
    else
        System.out.print(findMinLength(
               str.toCharArray()));
}
}
  
// This code is contributed by 29AjayKumar


Python3
# Python3 program to implement
# the above approach
  
# Function to check and return if
# substrings of length mid has a
# common character a
def check(st, mid, a):
  
    # Length of the string
    n = len(st)
  
    # Initialise the first
    # occurrence of character a
    previous = -1
  
    for i in range(n):
        if (st[i] == chr(a)):
  
            # Check that distance b/w
            # the current and previous
            # occurrence of character a
            # is less than or equal to mid
            if (i - previous > mid):
                return False
              
            previous = i     
  
    # If distance exceeds mid
    if (i - previous > mid):
        return False
    else:
        return True
  
# Function to check for all the
# alphabets, if substrings of
# length mid have a character common
def possible(st, mid):
  
    # Check for all 26 alphabets
    for i in range(26):
  
        # Check that char i + a is
        # common in all the substrings
        # of length mid
        if (check(st, mid, i + ord('a'))):
            return True
  
    # If no characters is common
    return False
  
# Function to calculate and return
# the minm length of substrings
def findMinLength(st):
  
    # Initialise low and high
    low = 1
    high = len(st)
  
    # Perform binary search
    while (low <= high):
  
        # Update mid
        mid = (low + high) // 2
  
        # Check if one common character is
        # present in the length of the mid
        if (possible(st, mid)):
            high = mid - 1
        else:
            low = mid + 1
  
    # Returns the minimum length
    # that contain one
    # common character
    return high + 1
  
# Function to check if all
# characters are distinct
def ifAllDistinct( st):
  
    s = []
    for c in st:
        s.append(c)
      
    return len(set(s)) == len(st)
  
# Driver Code
if __name__ == "__main__":
  
    st = "geeksforgeeks"
  
    if (ifAllDistinct(st)):
        print("-1")
    else:
        print(findMinLength(st))
  
# This code is contributed by chitranayal


C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
  
class GFG{
  
// Function to check and return if
// subStrings of length mid has a
// common character a
static bool check(char[] str, int mid, 
                  char a)
{
  
    // Length of the String
    int n = str.Length;
  
    // Initialise the first
    // occurrence of character a
    int previous = -1, i;
  
    for(i = 0; i < n; ++i) 
    {
        if (str[i] == a) 
        {
              
            // Check that distance b/w
            // the current and previous
            // occurrence of character a
            // is less than or equal to mid
            if (i - previous > mid)
            {
                return false;
            }
            previous = i;
        }
    }
  
    // If distance exceeds mid
    if (i - previous > mid)
        return false;
    else
        return true;
}
  
// Function to check for all the
// alphabets, if subStrings of
// length mid have a character common
static bool possible(char[] str, int mid)
{
  
    // Check for all 26 alphabets
    for(int i = 0; i < 26; ++i) 
    {
          
        // Check that char i + a is
        // common in all the subStrings
        // of length mid
        if (check(str, mid, (char)(i + 'a')))
            return true;
    }
  
    // If no characters is common
    return false;
}
  
// Function to calculate and return
// the minm length of subStrings
static int findMinLength(char[] str)
{
  
    // Initialise low and high
    int low = 1, high = str.Length;
  
    // Perform binary search
    while (low <= high)
    {
          
        // Update mid
        int mid = (low + high) / 2;
  
        // Check if one common character is
        // present in the length of the mid
        if (possible(str, mid))
            high = mid - 1;
        else
            low = mid + 1;
    }
  
    // Returns the minimum length
    // that contain one
    // common character
    return high + 1;
}
  
// Function to check if all
// characters are distinct
static bool ifAllDistinct(String str)
{
    HashSet s = new HashSet();
    foreach(char c in str.ToCharArray())
    {
        s.Add(c);
    }
    return s.Count == str.Length;
}
  
// Driver Code
public static void Main(String[] args)
{
    String str = "geeksforgeeks";
  
    if (ifAllDistinct(str))
        Console.Write(-1 + "\n");
    else
        Console.Write(findMinLength(
            str.ToCharArray()));
}
}
  
// This code is contributed by gauravrajput1


输出:
7

时间复杂度: O(26 * N * log(N))
辅助空间: O(1)