给定由小写字母组成的字符串str ,任务是找到最大数量的非重叠子字符串,使得每个子字符串包含整个字符串中所有出现的字符。如果存在多个具有相同子串数的解决方案,则打印总长度最小的解决方案。
例子:
Input: str = “abbaccd”
Output: bb cc d
Explanation:
The maximum number of substrings is such that all occurrences of its characters in the string are present.
The subtrings are {{d, bb, cc}, {d, abba, cc}}
Therefore, the substrings of smallest possible length are {d, bb, cc}.
Input: str = “adefaddaccc”
Output: e f ccc
方法:该问题可以使用贪心技术解决。请按照以下步骤解决问题:
- 初始化一个数组,比如res[] ,以存储所需的子字符串。
- 初始化两个数组,比如L[]和R[] ,分别存储给定字符串的所有可能字符的最左边和最右边的索引。
- 遍历字符串并存储给定字符串的所有可能字符的最左边和最右边的索引。
- 使用变量i遍历字符串并检查i是否是str[i]的最左边索引,检查从第 i个位置开始的由所有出现的str[i]组成的子字符串是否与由以下组成的任何子字符串不重叠不超过str[i -1] 的字符。如果发现为真,则将当前子字符串附加到res[] 中。
- 最后,打印res[]数组。
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Function to check if substring contains all
// occurrences of each character of str or not
int checkValid(string str,int i, int L[], int R[]){
// Stores rightmost index of str[i]
int right = R[str[i] - 'a'];
// Traverse the current substring
for (int j = i; j < right; j++){
// If leftmost index of str[j]
// less than i
if (L[str[j] - 'a'] < i)
return -1;
// Update right
right = max(right, R[str[j] - 'a']);
}
return right;
}
// Function to find maximum number of substring
// that satisfy the condition
vector maxcntOfSubstrings(string str) {
// Stores all substrings that
// satisfy the condition
vector res;
// Stores length of str
int n = str.length();
// Stores leftmost index
// of each character
int L[26];
// Stores rightmost index
// of each character
int R[26];
// Initialize L[] and R[]
for(int i = 0; i <26; i++) {
// Initialize L[i]
// and R[i]
L[i] = R[i] = -1;
}
// Traverse the string
for (int i = 0; i < n; i++) {
// If str[i] not
// already occurred
if (L[str[i] - 'a'] == -1) {
// Update leftmost index
// of str[i]
L[str[i] - 'a'] = i;
}
// Update rightmost index
// of str[i]
R[str[i]-'a'] = i;
}
// Stores rightmost index of last
// substring inserted into res[]
int right = -1;
// Traverse the string
for (int i = 0; i < n; i++) {
// If i is leftmost index of str[i]
if (i == L[str[i] - 'a']) {
// Check if a new substring starting
// from i satisfies the conditions or not
int new_right = checkValid(str, i,
L, R);
// If the substring starting from i
// satisfies the conditions
if(new_right != -1){
// Stores the substring starting from
// i that satisfy the condition
string sub = str.substr(i,
new_right - i + 1);
// If the substring overlaps
// with another substring
if(new_right < right){
// Stores sub to the last
// of res
res.back() = sub;
}
else {
// If sub not overlaps to
// other string then append
// sub to the end of res
res.push_back(sub);
}
// Update right
right = new_right;
}
}
}
return res;
}
// Driver Code
int main()
{
string str = "abbaccd";
// Stores maximum number of substring
// that satisfy the condition
vector res
= maxcntOfSubstrings(str);
// Print all substring
for(auto sub : res) {
cout<
Java
// Java program to implement
// the above approach
import java.util.*;
class GFG{
// Function to check if subString contains all
// occurrences of each character of str or not
static int checkValid(String str, int i,
int L[], int R[])
{
// Stores rightmost index of str.charAt(i)
int right = R[(int)(str.charAt(i)) - 97];
// Traverse the current subString
for(int j = i; j < right; j++)
{
// If leftmost index of str[j]
// less than i
if (L[(int)(str.charAt(j)) - 97] < i)
return -1;
// Update right
right = Math.max(right,
R[(int)(str.charAt(j)) - 97]);
}
return right;
}
// Function to find maximum number of subString
// that satisfy the condition
static Vector maxcntOfSubStrings(String str)
{
// Stores all subStrings that
// satisfy the condition
Vector res = new Vector();
// Stores length of str
int n = str.length();
// Stores leftmost index
// of each character
int []L = new int[26];
// Stores rightmost index
// of each character
int []R = new int[26];
// Initialize L[] and R[]
for(int i = 0; i < 26; i++)
{
// Initialize L[i]
// and R[i]
L[i] = R[i] = -1;
}
// Traverse the String
for(int i = 0; i < n; i++)
{
// If str.charAt(i) not
// already occurred
if (L[(int)(str.charAt(i)) - 97] == -1)
{
// Update leftmost index
// of str.charAt(i)
L[(int)(str.charAt(i)) - 97] = i;
}
// Update rightmost index
// of str.charAt(i)
R[(int)(str.charAt(i)) - 97] = i;
}
// Stores rightmost index of last
// subString inserted into res[]
int right = -1;
// Traverse the String
for(int i = 0; i < n; i++)
{
// If i is leftmost index of str.charAt(i)
if (i == L[(int)(str.charAt(i)) - 97])
{
// Check if a new subString starting
// from i satisfies the conditions or not
int new_right = checkValid(str, i, L, R);
// If the subString starting from i
// satisfies the conditions
if (new_right != -1)
{
// Stores the subString starting from
// i that satisfy the condition
String sub = str.substring(i,
new_right + 1);
// If the subString overlaps
// with another subString
if(new_right < right)
{
// Stores sub to the last
// of res
res.set(res.size() - 1, sub);
}
else
{
// If sub not overlaps to
// other String then append
// sub to the end of res
res.add(sub);
}
// Update right
right = new_right;
}
}
}
return res;
}
// Driver Code
public static void main(String args[])
{
String str = "abbaccd";
// Stores maximum number of subString
// that satisfy the condition
Vector res = maxcntOfSubStrings(str);
// Print all subString
for(int i = 0; i < res.size(); i++)
{
System.out.print(res.get(i) + " ");
}
}
}
// This code is contributed by SURENDRA_GANGWAR
Python3
# Python3 program to implement
# the above approach
# Function to check if subcontains
# all occurrences of each character
# of str or not
def checkValid(str,i, L, R):
# Stores rightmost index
# of str[i]
right = R[ord(str[i]) -
ord('a')]
# Traverse the current sub
for j in range(i, right):
# If leftmost index of str[j]
# less than i
if (L[ord(str[j]) -
ord('a')] < i):
return -1
# Update right
right = max(right, R[ord(str[j]) -
ord('a')])
return right
# Function to find maximum
# number of sub that satisfy
# the condition
def maxcntOfSubstrings(str):
# Stores all substrings that
# satisfy the condition
res = []
# Stores length of str
n = len(str)
# Stores leftmost index
# of each character
L = [-1] * 26
# Stores rightmost index
# of each character
R = [-1] * 26
for j, i in enumerate(str):
x = ord(i) - ord('a')
# If str[i] not
# already occurred
if L[x] == -1:
# Update leftmost index
# of str[i]
L[x] = j
# Update rightmost index
# of str[i]
R[x] = j
# Stores rightmost index of
# last substring inserted
# into res[]
right = -1
for j, i in enumerate(str):
x = ord(i) - ord('a')
# If i is leftmost index
# of str[i]
if j == L[x]:
# Check if a new substring
# starting from i satisfies
# the conditions or not
new_right = checkValid(str, j,
L, R)
# If the substring starting
# from i satisfies the conditions
if new_right != -1:
# Stores the substring starting
# from i that satisfy the condition
sub = str[j : new_right + 1]
# If the substring overlaps
# with another substring
if new_right < right:
res[-1] = sub
else:
# If sub not overlaps to
# other string then append
# sub to the end of res
res.append(sub)
right = new_right
return res
# Driver Code
if __name__ == '__main__':
str = "abbaccd"
# Stores maximum number of sub
# that satisfy the condition
res = maxcntOfSubstrings(str)
# Print sub
for sub in res:
print(sub, end = " ")
# This code is contributed by Mohit Kumar 29
C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG {
// Function to check if substring contains all
// occurrences of each character of str or not
static int checkValid(string str,int i, int[] L, int[] R)
{
// Stores rightmost index of str[i]
int right = R[str[i] - 'a'];
// Traverse the current substring
for (int j = i; j < right; j++){
// If leftmost index of str[j]
// less than i
if (L[str[j] - 'a'] < i)
return -1;
// Update right
right = Math.Max(right, R[str[j] - 'a']);
}
return right;
}
// Function to find maximum number of substring
// that satisfy the condition
static List maxcntOfSubstrings(string str)
{
// Stores all substrings that
// satisfy the condition
List res = new List();
// Stores length of str
int n = str.Length;
// Stores leftmost index
// of each character
int[] L = new int[26];
// Stores rightmost index
// of each character
int[] R = new int[26];
// Initialize L[] and R[]
for(int i = 0; i <26; i++)
{
// Initialize L[i]
// and R[i]
L[i] = R[i] = -1;
}
// Traverse the string
for (int i = 0; i < n; i++)
{
// If str[i] not
// already occurred
if (L[str[i] - 'a'] == -1)
{
// Update leftmost index
// of str[i]
L[str[i] - 'a'] = i;
}
// Update rightmost index
// of str[i]
R[str[i]-'a'] = i;
}
// Stores rightmost index of last
// substring inserted into res[]
int right = -1;
// Traverse the string
for (int i = 0; i < n; i++)
{
// If i is leftmost index of str[i]
if (i == L[str[i] - 'a'])
{
// Check if a new substring starting
// from i satisfies the conditions or not
int new_right = checkValid(str, i, L, R);
// If the substring starting from i
// satisfies the conditions
if(new_right != -1){
// Stores the substring starting from
// i that satisfy the condition
string sub = str.Substring(i, new_right - i + 1);
// If the substring overlaps
// with another substring
if(new_right < right){
// Stores sub to the last
// of res
res[res.Count - 1] = sub;
}
else {
// If sub not overlaps to
// other string then append
// sub to the end of res
res.Add(sub);
}
// Update right
right = new_right;
}
}
}
return res;
}
// Driver code
static void Main() {
string str = "abbaccd";
// Stores maximum number of substring
// that satisfy the condition
List res = maxcntOfSubstrings(str);
// Print all substring
foreach(string sub in res) {
Console.Write(sub + " ");
}
}
}
// This code is contributed by divyeshrabadiya
Javascript
输出:
bb cc d
时间复杂度: O(N * 26)
辅助空间: O(26)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live