给定长度为N的字符串S ,任务是在S 中找到最小的平衡子串。如果不存在这样的子字符串,则打印-1 。
A string is balanced if every letter in the string appears in both uppercase and lowercase, i.e “AabB” is a balanced string whereas “Ab” is not a balanced string.
例子:
Input: S = “azABaabba”
Output: ABaab
Explanation:
Substring {S[2], …, S[6]} (0-based indexing) is the smallest substring which is balanced.
Input: S = “Technocat”
Output: -1
朴素的方法:最简单的方法是生成给定字符串的所有可能子字符串,并检查是否存在满足给定条件的子字符串。打印所有此类子字符串中最小的一个。
时间复杂度: O(N 3 )
辅助空间: O(N)
Efficient Approach:为了优化上面的方式,思路是使用Sliding Window的概念。请按照以下步骤解决问题:
- 遍历给定的字符串并将输入字符串中仅出现小写或大写形式的字符存储在 Map mp 中。
- 初始化两个数组以跟踪到目前为止获得的小写和大写字符。
- 现在,遍历保持两个指针i和st (初始化为0 )的字符串,其中st将指向当前子字符串的开头, i将指向当前字符。
- 如果当前字符在mp 中,则忽略到目前为止获得的所有字符并从下一个字符开始并相应地调整数组。
- 如果当前字符不在mp 中,则借助st指针从子串的开头删除多余的字符,这样任何字符的频率都不会转换为0并相应地调整数组。
- 现在,检查子串{S[st], ….., S[i]}是否平衡。如果平衡且i – st + 1小于目前得到的平衡子串的长度。更新长度并存储子字符串的开始和结束索引,即分别为st和i 。
- 重复上述步骤直到字符串结束。
下面是上述方法的实现:
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