📌  相关文章
📜  每个字母都以大写和小写形式出现的最小子串

📅  最后修改于: 2021-09-07 03:02:05             🧑  作者: Mango

给定长度为N的字符串S ,任务是在S 中找到最小的平衡子串。如果不存在这样的子字符串,则打印-1

例子:

朴素的方法:最简单的方法是生成给定字符串的所有可能子字符串,并检查是否存在满足给定条件的子字符串。打印所有此类子字符串中最小的一个。

时间复杂度: O(N 3 )
辅助空间: O(N)

Efficient Approach:为了优化上面的方式,思路是使用Sliding Window的概念。请按照以下步骤解决问题:

  • 遍历给定的字符串并将输入字符串中仅出现小写或大写形式的字符存储在 Map mp 中
  • 初始化两个数组以跟踪到目前为止获得的小写和大写字符。
  • 现在,遍历保持两个指针ist (初始化为0 )的字符串,其中st将指向当前子字符串的开头, i将指向当前字符。
    • 如果当前字符在mp 中,则忽略到目前为止获得的所有字符并从下一个字符开始并相应地调整数组。
    • 如果当前字符不在mp 中,则借助st指针从子串的开头删除多余的字符,这样任何字符的频率都不会转换为0并相应地调整数组。
    • 现在,检查子串{S[st], ….., S[i]}是否平衡。如果平衡且i – st + 1小于目前得到的平衡子串的长度。更新长度并存储子字符串的开始和结束索引,即分别为sti
    • 重复上述步骤直到字符串结束。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to check if the current
// string is balanced or not
bool balanced(int small[], int caps[])
{
    // For every character, check if
    // there exists uppercase as well
    // as lowercase characters
    for (int i = 0; i < 26; i++) {
 
        if (small[i] != 0 && (caps[i] == 0))
            return 0;
 
        else if ((small[i] == 0) && (caps[i] != 0))
            return 0;
    }
    return 1;
}
 
// Function to find smallest length substring
// in the given string which is balanced
void smallestBalancedSubstring(string s)
{
 
    // Store frequency of
    // lowercase characters
    int small[26];
 
    // Stores frequency of
    // uppercase characters
    int caps[26];
 
    memset(small, 0, sizeof(small));
    memset(caps, 0, sizeof(caps));
 
    // Count frequency of characters
    for (int i = 0; i < s.length(); i++) {
 
        if (s[i] >= 65 && s[i] <= 90)
            caps[s[i] - 'A']++;
        else
            small[s[i] - 'a']++;
    }
 
    // Mark those characters which
    // are not present in both
    // lowercase and uppercase
    unordered_map mp;
    for (int i = 0; i < 26; i++) {
 
        if (small[i] && !caps[i])
            mp[char(i + 'a')] = 1;
 
        else if (caps[i] && !small[i])
            mp[char(i + 'A')] = 1;
    }
 
    // Initialize the frequencies
    // back to 0
    memset(small, 0, sizeof(small));
    memset(caps, 0, sizeof(caps));
 
    // Marks the start and
    // end of current substring
    int i = 0, st = 0;
 
    // Marks the start and end
    // of required substring
    int start = -1, end = -1;
 
    // Stores the length of
    // smallest balanced substring
    int minm = INT_MAX;
 
    while (i < s.length()) {
        if (mp[s[i]]) {
 
            // Remove all characters
            // obtained so far
            while (st < i) {
 
                if (s[st] >= 65 && s[st] <= 90)
                    caps[s[st] - 'A']--;
                else
                    small[s[st] - 'a']--;
 
                st++;
            }
            i += 1;
            st = i;
        }
        else {
 
            if (s[i] >= 65 && s[i] <= 90)
                caps[s[i] - 'A']++;
            else
                small[s[i] - 'a']++;
 
            // Remove extra characters from
            // front of the current substring
            while (1) {
 
                if (s[st] >= 65 && s[st] <= 90
                    && caps[s[st] - 'A'] > 1) {
                    caps[s[st] - 'A']--;
                    st++;
                }
                else if (s[st] >= 97 && s[st] <= 122
                         && small[s[st] - 'a'] > 1) {
                    small[s[st] - 'a']--;
                    st++;
                }
                else
                    break;
            }
 
            // If substring (st, i) is balanced
            if (balanced(small, caps)) {
 
                if (minm > (i - st + 1)) {
 
                    minm = i - st + 1;
                    start = st;
                    end = i;
                }
            }
            i += 1;
        }
    }
 
    // No balanced substring
    if (start == -1 || end == -1)
        cout << -1 << endl;
 
    // Store answer string
    else {
 
        string ans = "";
        for (int i = start; i <= end; i++)
            ans += s[i];
        cout << ans << endl;
    }
}
 
// Driver Code
int main()
{
 
    // Given string
    string s = "azABaabba";
 
    smallestBalancedSubstring(s);
 
    return 0;
}


Java
// Java program for the above approach
import java.io.*;
import java.util.*;
 
class GFG{
 
// Function to check if the current
// string is balanced or not
static boolean balanced(int small[],
                        int caps[])
{
     
    // For every character, check if
    // there exists uppercase as well
    // as lowercase characters
    for(int i = 0; i < 26; i++)
    {
        if (small[i] != 0 && (caps[i] == 0))
            return false;
 
        else if ((small[i] == 0) && (caps[i] != 0))
            return false;
    }
    return true;
}
 
// Function to find smallest length substring
// in the given string which is balanced
static void smallestBalancedSubstring(String s)
{
     
    // Store frequency of
    // lowercase characters
    int[] small = new int[26];
 
    // Stores frequency of
    // uppercase characters
    int[] caps = new int[26];
 
    Arrays.fill(small, 0);
    Arrays.fill(caps, 0);
 
    // Count frequency of characters
    for(int i = 0; i < s.length(); i++)
    {
        if (s.charAt(i) >= 65 && s.charAt(i) <= 90)
            caps[s.charAt(i) - 'A']++;
        else
            small[s.charAt(i) - 'a']++;
    }
 
    // Mark those characters which
    // are not present in both
    // lowercase and uppercase
    Map mp = new HashMap();
 
    for(int i = 0; i < 26; i++)
    {
        if (small[i] != 0 && caps[i] == 0)
            mp.put((char)(i + 'a'), 1);
        else if (caps[i] != 0 && small[i] == 0)
            mp.put((char)(i + 'A'), 1);
        // mp[char(i + 'A')] = 1;
    }
 
    // Initialize the frequencies
    // back to 0
    Arrays.fill(small, 0);
    Arrays.fill(caps, 0);
 
    // Marks the start and
    // end of current substring
    int i = 0, st = 0;
 
    // Marks the start and end
    // of required substring
    int start = -1, end = -1;
 
    // Stores the length of
    // smallest balanced substring
    int minm = Integer.MAX_VALUE;
 
    while (i < s.length())
    {
        if (mp.get(s.charAt(i)) != null)
        {
             
            // Remove all characters
            // obtained so far
            while (st < i)
            {
                if (s.charAt(st) >= 65 &&
                    s.charAt(st) <= 90)
                    caps[s.charAt(st) - 'A']--;
                else
                    small[s.charAt(st) - 'a']--;
 
                st++;
            }
            i += 1;
            st = i;
        }
        else
        {
            if (s.charAt(i) >= 65 && s.charAt(i) <= 90)
                caps[s.charAt(i) - 'A']++;
            else
                small[s.charAt(i) - 'a']++;
 
            // Remove extra characters from
            // front of the current substring
            while (true)
            {
                if (s.charAt(st) >= 65 &&
                    s.charAt(st) <= 90 &&
                    caps[s.charAt(st) - 'A'] > 1)
                {
                    caps[s.charAt(st) - 'A']--;
                    st++;
                }
                else if (s.charAt(st) >= 97 &&
                         s.charAt(st) <= 122 &&
                         small[s.charAt(st) - 'a'] > 1)
                {
                    small[s.charAt(st) - 'a']--;
                    st++;
                }
                else
                    break;
            }
 
            // If substring (st, i) is balanced
            if (balanced(small, caps))
            {
                if (minm > (i - st + 1))
                {
                    minm = i - st + 1;
                    start = st;
                    end = i;
                }
            }
            i += 1;
        }
    }
 
    // No balanced substring
    if (start == -1 || end == -1)
        System.out.println(-1);
 
    // Store answer string
    else
    {
        String ans = "";
        for(int j = start; j <= end; j++)
            ans += s.charAt(j);
             
        System.out.println(ans);
    }
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given string
    String s = "azABaabba";
 
    smallestBalancedSubstring(s);
}
}
 
// This code is contributed by Dharanendra L V


Python3
# python 3 program for the above approach
import sys
 
# Function to check if the current
# string is balanced or not
def balanced(small, caps):
   
    # For every character, check if
    # there exists uppercase as well
    # as lowercase characters
    for i in range(26):
        if (small[i] != 0 and (caps[i] == 0)):
            return 0
 
        elif((small[i] == 0) and (caps[i] != 0)):
            return 0
    return 1
 
# Function to find smallest length substring
# in the given string which is balanced
def smallestBalancedSubstring(s):
   
    # Store frequency of
    # lowercase characters
    small = [0 for i in range(26)]
 
    # Stores frequency of
    # uppercase characters
    caps = [0 for i in range(26)]
 
    # Count frequency of characters
    for i in range(len(s)):
        if (ord(s[i]) >= 65 and ord(s[i]) <= 90):
            caps[ord(s[i]) - 65] += 1
        else:
            small[ord(s[i]) - 97] += 1
 
    # Mark those characters which
    # are not present in both
    # lowercase and uppercase
    mp = {}
    for i in range(26):
        if (small[i] and caps[i]==0):
            mp[chr(i + 97)] = 1
 
        elif (caps[i] and small[i]==0):
            mp[chr(i + 65)] = 1
 
    # Initialize the frequencies
    # back to 0
    for i in range(len(small)):
        small[i] = 0
        caps[i] = 0
 
    # Marks the start and
    # end of current substring
    i = 0
    st = 0
 
    # Marks the start and end
    # of required substring
    start = -1
    end = -1
 
    # Stores the length of
    # smallest balanced substring
    minm = sys.maxsize
 
    while (i < len(s)):
        if(s[i] in mp):
           
            # Remove all characters
            # obtained so far
            while (st < i):
                if (ord(s[st]) >= 65 and ord(s[st]) <= 90):
                    caps[ord(s[st]) - 65] -= 1
                else:
                    small[ord(s[st]) - 97] -= 1
 
                st += 1
            i += 1
            st = i
        else:
            if (ord(s[i]) >= 65 and ord(s[i]) <= 90):
                caps[ord(s[i]) - 65] += 1
            else:
                small[ord(s[i] )- 97] += 1
 
            # Remove extra characters from
            # front of the current substring
            while (1):
                if (ord(s[st]) >= 65 and ord(s[st])<= 90 and caps[ord(s[st])- 65] > 1):
                    caps[ord(s[st]) - 65] -= 1
                    st += 1
                elif (ord(s[st]) >= 97 and ord(s[st]) <= 122 and small[ord(s[st]) - 97] > 1):
                    small[ord(s[st]) - 97] -= 1
                    st += 1
                else:
                    break
 
            # If substring (st, i) is balanced
            if (balanced(small, caps)):
                if (minm > (i - st + 1)):
                    minm = i - st + 1
                    start = st
                    end = i
            i += 1
 
    # No balanced substring
    if (start == -1 or end == -1):
        print(-1)
 
    # Store answer string
    else:
        ans = ""
        for i in range(start,end+1,1):
            ans +=  s[i]
        print(ans)
 
# Driver Code
if __name__ == '__main__':
   
    # Given string
    s = "azABaabba"
    smallestBalancedSubstring(s)
     
    # This code is contributed by bgangwar59.


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG
{
  public const int MaxValue = 2147483647;
 
  // Function to check if the current
  // string is balanced or not
  static bool balanced(int []small,
                       int []caps)
  {
 
    // For every character, check if
    // there exists uppercase as well
    // as lowercase characters
    for(int i = 0; i < 26; i++)
    {
      if (small[i] != 0 && (caps[i] == 0))
        return false;
 
      else if ((small[i] == 0) && (caps[i] != 0))
        return false;
    }
    return true;
  }
 
  // Function to find smallest length substring
  // in the given string which is balanced
  static void smallestBalancedSubstring(string s)
  {
 
    // Store frequency of
    // lowercase characters
    int[] small = new int[26];
    int i;
 
    // Stores frequency of
    // uppercase characters
    int[] caps = new int[26];
    Array.Clear(small, 0, small.Length);
    Array.Clear(caps, 0, caps.Length);
 
    // Count frequency of characters
    for(i = 0; i < s.Length; i++)
    {
      if (s[i] >= 65 && s[i] <= 90)
        caps[(int)s[i] - 65]++;
      else
        small[(int)s[i]- 97]++;
    }
 
    // Mark those characters which
    // are not present in both
    // lowercase and uppercase
    Dictionary mp = new Dictionary();
 
    for(i = 0; i < 26; i++)
    {
      if (small[i] != 0 && caps[i] == 0){
        mp[(char)(i+97)] = 1;
      }
      else if (caps[i] != 0 && small[i] == 0)
        mp[(char)(i+65)] = 1;
      // mp[char(i + 'A')] = 1;
    }
 
    // Initialize the frequencies
    // back to 0
    Array.Clear(small, 0, small.Length);
    Array.Clear(caps, 0, caps.Length);
 
    // Marks the start and
    // end of current substring
    i = 0;
    int st = 0;
 
    // Marks the start and end
    // of required substring
    int start = -1, end = -1;
 
    // Stores the length of
    // smallest balanced substring
    int minm = MaxValue;
 
    while (i < s.Length)
    {
      if (mp.ContainsKey(s[i]))
      {
 
        // Remove all characters
        // obtained so far
        while (st < i)
        {
          if ((int)s[st] >= 65 &&
              (int)s[st] <= 90)
            caps[(int)s[st] - 65]--;
          else
            small[(int)s[st] - 97]--;
 
          st++;
        }
        i += 1;
        st = i;
      }
      else
      {
        if ((int)s[i] >= 65 && (int)s[i] <= 90)
          caps[(int)s[i] - 65]++;
        else
          small[(int)s[i] - 97]++;
 
        // Remove extra characters from
        // front of the current substring
        while (true)
        {
          if ((int)s[st] >= 65 &&
              (int)s[st] <= 90 &&
              caps[(int)s[st] - 65] > 1)
          {
            caps[(int)s[st] - 65]--;
            st++;
          }
          else if ((int)s[st] >= 97 &&
                   (int)s[st] <= 122 &&
                   small[(int)s[st] - 97] > 1)
          {
            small[(int)s[st] - 97]--;
            st++;
          }
          else
            break;
        }
 
        // If substring (st, i) is balanced
        if (balanced(small, caps))
        {
          if (minm > (i - st + 1))
          {
            minm = i - st + 1;
            start = st;
            end = i;
          }
        }
        i += 1;
      }
    }
 
    // No balanced substring
    if (start == -1 || end == -1)
      Console.WriteLine(-1);
 
    // Store answer string
    else
    {
      string ans = "";
      for(int j = start; j <= end; j++)
        ans += s[j];
 
      Console.WriteLine(ans);
    }
  }
 
  // Driver Code
  public static void Main()
  {
 
    // Given string
    string s = "azABaabba";
 
    smallestBalancedSubstring(s);
  }
}
 
// This code is contributed by SURENDRA_GANGWAR.


输出:
ABaab

时间复杂度: O(N)
辅助空间: O(N)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live