给定字符串S ,任务是计算将字符串分成两个非空部分的方式,以使这两个部分具有相同数量的不同字符。
例子:
Input: S = “aaaa”
Output: 3
Explanation:
There can be three ways to partition the string –
{{a, aaa}, {aa, aa}, {aaa, a}}
Input: S = “ababa”
Output: 2
Explanation:
There can be two ways to partition the string –
{{ab, aba}, {aba, ba}}
天真的方法:这个想法是选择字符串的每个可能的分区点,并为每个分区计算分区后的字符串的不同字符。如果两个分区字符串中不同字符的数量相等,则将路数增加1。
下面是上述方法的实现:
C++
// C++ implementation to count the
// number of ways to partition the
// string such that each partition
// have same number of distinct
// characters in the string
#include
using namespace std;
// Function to count the distinct
// characters in the string
int distinctChars(string s)
{
// Frequency of each character
int freq[26] = { 0 };
int count = 0;
// Loop to count the frequency
// of each character of the string
for (int i = 0; i < s.length(); i++)
freq[s[i] - 'a']++;
// If frequency is greater than 0
// then the character occured
for (int i = 0; i < 26; i++) {
if (freq[i] > 0)
count++;
}
return count;
}
// Function to count the number
// of ways to partition the string
// such that each partition have
// same number of distinct character
int waysToSplit(string s)
{
int n = s.length();
int answer = 0;
// Loop to choose the partition
// index for the string
for (int i = 1; i < n; i++) {
// Divide in two parts
string left = s.substr(0, i);
string right = s.substr(i, n - i);
// Check whether number of distinct
// characters are equal
if (distinctChars(left) ==
distinctChars(right))
answer++;
}
return answer;
}
// Driver Code
int main()
{
string s = "ababa";
cout << waysToSplit(s);
return 0;
}
Java
// Java implementation to count the
// number of ways to partition the
// String such that each partition
// have same number of distinct
// characters in the String
class GFG{
// Function to count the distinct
// characters in the String
static int distinctChars(String s)
{
// Frequency of each character
int freq[] = new int[26];
int count = 0;
// Loop to count the frequency
// of each character of the String
for (int i = 0; i < s.length(); i++)
freq[s.charAt(i) - 'a']++;
// If frequency is greater than 0
// then the character occured
for (int i = 0; i < 26; i++) {
if (freq[i] > 0)
count++;
}
return count;
}
// Function to count the number
// of ways to partition the String
// such that each partition have
// same number of distinct character
static int waysToSplit(String s)
{
int n = s.length();
int answer = 0;
// Loop to choose the partition
// index for the String
for (int i = 1; i < n; i++) {
// Divide in two parts
String left = s.substring(0, i);
String right = s.substring(i, n);
// Check whether number of distinct
// characters are equal
if (distinctChars(left) ==
distinctChars(right))
answer++;
}
return answer;
}
// Driver Code
public static void main(String[] args)
{
String s = "ababa";
System.out.print(waysToSplit(s));
}
}
// This code is contributed by sapnasingh4991
Python3
# Python3 implementation to count the
# number of ways to partition the
# string such that each partition
# have same number of distinct
# characters in the string
# Function to count the distinct
# characters in the string
def distinctChars(s) :
# Frequency of each character
freq = [0]*26;
count = 0;
# Loop to count the frequency
# of each character of the string
for i in range(len(s)) :
freq[ord(s[i]) - ord('a')] += 1;
# If frequency is greater than 0
# then the character occured
for i in range(26) :
if (freq[i] > 0) :
count += 1;
return count;
# Function to count the number
# of ways to partition the string
# such that each partition have
# same number of distinct character
def waysToSplit(s) :
n = len(s);
answer = 0;
# Loop to choose the partition
# index for the string
for i in range(1, n) :
# Divide in two parts
left = s[0 : i];
right = s[i : n ];
# Check whether number of distinct
# characters are equal
if (distinctChars(left) == distinctChars(right)) :
answer += 1;
return answer;
# Driver Code
if __name__ == "__main__" :
s = "ababa";
print(waysToSplit(s));
# This code is contributed by Yash_R
C#
// C# implementation to count the
// number of ways to partition the
// String such that each partition
// have same number of distinct
// characters in the String
using System;
class GFG{
// Function to count the distinct
// characters in the String
static int distinctChars(string s)
{
// Frequency of each character
int []freq = new int[26];
int count = 0;
// Loop to count the frequency
// of each character of the String
for (int i = 0; i < s.Length; i++)
freq[s[i] - 'a']++;
// If frequency is greater than 0
// then the character occured
for (int i = 0; i < 26; i++) {
if (freq[i] > 0)
count++;
}
return count;
}
// Function to count the number
// of ways to partition the String
// such that each partition have
// same number of distinct character
static int waysToSplit(string s)
{
int n = s.Length;
int answer = 0;
// Loop to choose the partition
// index for the String
for (int i = 1; i < n; i++) {
// Divide in two parts
string left = s.Substring(0, i);
string right = s.Substring(i, n-i);
// Check whether number of distinct
// characters are equal
if (distinctChars(left) ==
distinctChars(right))
answer++;
}
return answer;
}
// Driver Code
public static void Main(string[] args)
{
string s = "ababa";
Console.WriteLine(waysToSplit(s));
}
}
// This code is contributed by Yash_R
C++
// C++ implementation to count the
// number of ways to partition the
// string such that each partition
// have same number of distinct
// characters in the string
#include
using namespace std;
// Function to count the number
// of ways to partition the string
// such that each partition have
// same number of distinct character
int waysToSplit(string s)
{
int n = s.length();
int answer = 0;
// Prefix and suffix array for
// distinct character from
// start and end
int prefix[n] = { 0 };
int suffix[n] = { 0 };
// To check whether a character
// has appeared till ith index
int seen[26] = { 0 };
// Calculating prefix array
for (int i = 0; i < n; i++) {
int prev = (i - 1 >= 0 ?
prefix[i - 1] : 0);
// Character appears for
// the first time in string
if (seen[s[i] - 'a'] == 0) {
prefix[i] += (prev + 1);
}
else
prefix[i] = prev;
// Character is visited
seen[s[i] - 'a'] = 1;
}
// Resetting seen for
// suffix calculation
memset(seen, 0, sizeof(seen));
// Calculating the suffix array
suffix[n - 1] = 0;
for (int i = n - 1; i >= 1; i--) {
int prev = suffix[i];
// Character appears
// for the first time
if (seen[s[i] - 'a'] == 0) {
suffix[i - 1] += (prev + 1);
}
else
suffix[i - 1] = prev;
// This character
// has now appeared
seen[s[i] - 'a'] = 1;
}
// Loop to calculate the number
// partition points in the string
for (int i = 0; i < n; i++) {
// Check whether number of
// distinct characters are equal
if (prefix[i] == suffix[i])
answer++;
}
return answer;
}
// Driver Code
int main()
{
string s = "ababa";
cout << waysToSplit(s);
return 0;
}
Java
// Java implementation to count the
// number of ways to partition the
// string such that each partition
// have same number of distinct
// characters in the string
class GFG {
// Function to count the number
// of ways to partition the string
// such that each partition have
// same number of distinct character
static int waysToSplit(String s)
{
int n = s.length();
int answer = 0;
// Prefix and suffix array for
// distinct character from
// start and end
int prefix[] = new int[n] ;
int suffix[] = new int[n];
// To check whether a character
// has appeared till ith index
int seen[] = new int[26];
// Calculating prefix array
for (int i = 0; i < n; i++) {
int prev = (i - 1 >= 0 ?
prefix[i - 1] : 0);
// Character appears for
// the first time in string
if (seen[s.charAt(i) - 'a'] == 0) {
prefix[i] += (prev + 1);
}
else
prefix[i] = prev;
// Character is visited
seen[s.charAt(i)- 'a'] = 1;
}
// Resetting seen for
// suffix calculation
for(int i = 0; i <26; i++)
seen[i] = 0;
// Calculating the suffix array
suffix[n - 1] = 0;
for (int i = n - 1; i >= 1; i--) {
int prev = suffix[i];
// Character appears
// for the first time
if (seen[s.charAt(i) - 'a'] == 0) {
suffix[i - 1] += (prev + 1);
}
else
suffix[i - 1] = prev;
// This character
// has now appeared
seen[s.charAt(i)- 'a'] = 1;
}
// Loop to calculate the number
// partition points in the string
for (int i = 0; i < n; i++) {
// Check whether number of
// distinct characters are equal
if (prefix[i] == suffix[i])
answer++;
}
return answer;
}
// Driver Code
public static void main (String[] args)
{
String s = "ababa";
System.out.println(waysToSplit(s));
}
}
// This code is contributed by Yash_R
Python3
# Python3 implementation to count the
# number of ways to partition the
# string such that each partition
# have same number of distinct
# characters in the string
# Function to count the number
# of ways to partition the string
# such that each partition have
# same number of distinct character
def waysToSplit(s) :
n = len(s);
answer = 0;
# Prefix and suffix array for
# distinct character from
# start and end
prefix = [ 0 ]*n;
suffix = [0 ]*n;
# To check whether a character
# has appeared till ith index
seen = [ 0 ]*26;
# Calculating prefix array
for i in range(n) :
prev = prefix[i - 1] if (i - 1 >= 0 ) else 0;
# Character appears for
# the first time in string
if (seen[ord(s[i]) - ord('a')] == 0) :
prefix[i] += (prev + 1);
else :
prefix[i] = prev;
# Character is visited
seen[ord(s[i]) - ord('a')] = 1;
# Resetting seen for
# suffix calculation
seen = [0]*len(seen);
# Calculating the suffix array
suffix[n - 1] = 0;
for i in range(n - 1, 0, -1) :
prev = suffix[i];
# Character appears
# for the first time
if (seen[ord(s[i]) - ord('a')] == 0) :
suffix[i - 1] += (prev + 1);
else :
suffix[i - 1] = prev;
# This character
# has now appeared
seen[ord(s[i]) - ord('a')] = 1;
# Loop to calculate the number
# partition points in the string
for i in range(n) :
# Check whether number of
# distinct characters are equal
if (prefix[i] == suffix[i]) :
answer += 1;
return answer;
# Driver Code
if __name__ == "__main__" :
s = "ababa";
print(waysToSplit(s));
# This code is contributed by Yash_R
C#
// C# implementation to count the
// number of ways to partition the
// string such that each partition
// have same number of distinct
// characters in the string
using System;
public class GFG {
// Function to count the number
// of ways to partition the string
// such that each partition have
// same number of distinct character
static int waysToSplit(string s)
{
int n = s.Length;
int answer = 0;
// Prefix and suffix array for
// distinct character from
// start and end
int []prefix = new int[n] ;
int []suffix = new int[n];
// To check whether a character
// has appeared till ith index
int []seen = new int[26];
// Calculating prefix array
for (int i = 0; i < n; i++) {
int prev = (i - 1 >= 0 ? prefix[i - 1] : 0);
// Character appears for
// the first time in string
if (seen[s[i] - 'a'] == 0) {
prefix[i] += (prev + 1);
}
else
prefix[i] = prev;
// Character is visited
seen[s[i]- 'a'] = 1;
}
// Resetting seen for
// suffix calculation
for(int i = 0; i <26; i++)
seen[i] = 0;
// Calculating the suffix array
suffix[n - 1] = 0;
for (int i = n - 1; i >= 1; i--) {
int prev = suffix[i];
// Character appears
// for the first time
if (seen[s[i] - 'a'] == 0) {
suffix[i - 1] += (prev + 1);
}
else
suffix[i - 1] = prev;
// This character
// has now appeared
seen[s[i]- 'a'] = 1;
}
// Loop to calculate the number
// partition points in the string
for (int i = 0; i < n; i++) {
// Check whether number of
// distinct characters are equal
if (prefix[i] == suffix[i])
answer++;
}
return answer;
}
// Driver Code
public static void Main (string[] args)
{
string s = "ababa";
Console.WriteLine(waysToSplit(s));
}
}
// This code is contributed by Yash_R
输出:
2
时间复杂度: O(N 2 )
辅助空间: O(26)
有效的方法:我们的想法是预先计算的鲜明字符与哈希地图的帮助访问字符和前缀和后缀和阵列从开始的不同字符字符串的当前索引每个可能的子字符串。下面是步骤说明:
- 遍历每个可能的索引的字符串,并计算从开始到该索引的不同字符数。
- 如果是第一次访问当前索引字符,则将上一个索引中不同字符的计数增加1。
if (visited[s[i]] == False) prefix[i] = prefix[i-1] + 1
- 如果较早访问了当前索引字符,则从起始索引到当前索引的不同字符数将等于最后一个索引的不同字符。那是 –
if (visited[s[i]] == True) prefix[i] = prefix[i-1]
- 如果是第一次访问当前索引字符,则将上一个索引中不同字符的计数增加1。
- 最后,遍历字符串,并且对于每个分区字符串,对于每个索引,不同字符的计数都可以计算为–
Count in left partitioned string = prefix[i] Count in right partitioned string = prefix[L] - prefix[i+1]
下面是上述方法的实现:
C++
// C++ implementation to count the
// number of ways to partition the
// string such that each partition
// have same number of distinct
// characters in the string
#include
using namespace std;
// Function to count the number
// of ways to partition the string
// such that each partition have
// same number of distinct character
int waysToSplit(string s)
{
int n = s.length();
int answer = 0;
// Prefix and suffix array for
// distinct character from
// start and end
int prefix[n] = { 0 };
int suffix[n] = { 0 };
// To check whether a character
// has appeared till ith index
int seen[26] = { 0 };
// Calculating prefix array
for (int i = 0; i < n; i++) {
int prev = (i - 1 >= 0 ?
prefix[i - 1] : 0);
// Character appears for
// the first time in string
if (seen[s[i] - 'a'] == 0) {
prefix[i] += (prev + 1);
}
else
prefix[i] = prev;
// Character is visited
seen[s[i] - 'a'] = 1;
}
// Resetting seen for
// suffix calculation
memset(seen, 0, sizeof(seen));
// Calculating the suffix array
suffix[n - 1] = 0;
for (int i = n - 1; i >= 1; i--) {
int prev = suffix[i];
// Character appears
// for the first time
if (seen[s[i] - 'a'] == 0) {
suffix[i - 1] += (prev + 1);
}
else
suffix[i - 1] = prev;
// This character
// has now appeared
seen[s[i] - 'a'] = 1;
}
// Loop to calculate the number
// partition points in the string
for (int i = 0; i < n; i++) {
// Check whether number of
// distinct characters are equal
if (prefix[i] == suffix[i])
answer++;
}
return answer;
}
// Driver Code
int main()
{
string s = "ababa";
cout << waysToSplit(s);
return 0;
}
Java
// Java implementation to count the
// number of ways to partition the
// string such that each partition
// have same number of distinct
// characters in the string
class GFG {
// Function to count the number
// of ways to partition the string
// such that each partition have
// same number of distinct character
static int waysToSplit(String s)
{
int n = s.length();
int answer = 0;
// Prefix and suffix array for
// distinct character from
// start and end
int prefix[] = new int[n] ;
int suffix[] = new int[n];
// To check whether a character
// has appeared till ith index
int seen[] = new int[26];
// Calculating prefix array
for (int i = 0; i < n; i++) {
int prev = (i - 1 >= 0 ?
prefix[i - 1] : 0);
// Character appears for
// the first time in string
if (seen[s.charAt(i) - 'a'] == 0) {
prefix[i] += (prev + 1);
}
else
prefix[i] = prev;
// Character is visited
seen[s.charAt(i)- 'a'] = 1;
}
// Resetting seen for
// suffix calculation
for(int i = 0; i <26; i++)
seen[i] = 0;
// Calculating the suffix array
suffix[n - 1] = 0;
for (int i = n - 1; i >= 1; i--) {
int prev = suffix[i];
// Character appears
// for the first time
if (seen[s.charAt(i) - 'a'] == 0) {
suffix[i - 1] += (prev + 1);
}
else
suffix[i - 1] = prev;
// This character
// has now appeared
seen[s.charAt(i)- 'a'] = 1;
}
// Loop to calculate the number
// partition points in the string
for (int i = 0; i < n; i++) {
// Check whether number of
// distinct characters are equal
if (prefix[i] == suffix[i])
answer++;
}
return answer;
}
// Driver Code
public static void main (String[] args)
{
String s = "ababa";
System.out.println(waysToSplit(s));
}
}
// This code is contributed by Yash_R
Python3
# Python3 implementation to count the
# number of ways to partition the
# string such that each partition
# have same number of distinct
# characters in the string
# Function to count the number
# of ways to partition the string
# such that each partition have
# same number of distinct character
def waysToSplit(s) :
n = len(s);
answer = 0;
# Prefix and suffix array for
# distinct character from
# start and end
prefix = [ 0 ]*n;
suffix = [0 ]*n;
# To check whether a character
# has appeared till ith index
seen = [ 0 ]*26;
# Calculating prefix array
for i in range(n) :
prev = prefix[i - 1] if (i - 1 >= 0 ) else 0;
# Character appears for
# the first time in string
if (seen[ord(s[i]) - ord('a')] == 0) :
prefix[i] += (prev + 1);
else :
prefix[i] = prev;
# Character is visited
seen[ord(s[i]) - ord('a')] = 1;
# Resetting seen for
# suffix calculation
seen = [0]*len(seen);
# Calculating the suffix array
suffix[n - 1] = 0;
for i in range(n - 1, 0, -1) :
prev = suffix[i];
# Character appears
# for the first time
if (seen[ord(s[i]) - ord('a')] == 0) :
suffix[i - 1] += (prev + 1);
else :
suffix[i - 1] = prev;
# This character
# has now appeared
seen[ord(s[i]) - ord('a')] = 1;
# Loop to calculate the number
# partition points in the string
for i in range(n) :
# Check whether number of
# distinct characters are equal
if (prefix[i] == suffix[i]) :
answer += 1;
return answer;
# Driver Code
if __name__ == "__main__" :
s = "ababa";
print(waysToSplit(s));
# This code is contributed by Yash_R
C#
// C# implementation to count the
// number of ways to partition the
// string such that each partition
// have same number of distinct
// characters in the string
using System;
public class GFG {
// Function to count the number
// of ways to partition the string
// such that each partition have
// same number of distinct character
static int waysToSplit(string s)
{
int n = s.Length;
int answer = 0;
// Prefix and suffix array for
// distinct character from
// start and end
int []prefix = new int[n] ;
int []suffix = new int[n];
// To check whether a character
// has appeared till ith index
int []seen = new int[26];
// Calculating prefix array
for (int i = 0; i < n; i++) {
int prev = (i - 1 >= 0 ? prefix[i - 1] : 0);
// Character appears for
// the first time in string
if (seen[s[i] - 'a'] == 0) {
prefix[i] += (prev + 1);
}
else
prefix[i] = prev;
// Character is visited
seen[s[i]- 'a'] = 1;
}
// Resetting seen for
// suffix calculation
for(int i = 0; i <26; i++)
seen[i] = 0;
// Calculating the suffix array
suffix[n - 1] = 0;
for (int i = n - 1; i >= 1; i--) {
int prev = suffix[i];
// Character appears
// for the first time
if (seen[s[i] - 'a'] == 0) {
suffix[i - 1] += (prev + 1);
}
else
suffix[i - 1] = prev;
// This character
// has now appeared
seen[s[i]- 'a'] = 1;
}
// Loop to calculate the number
// partition points in the string
for (int i = 0; i < n; i++) {
// Check whether number of
// distinct characters are equal
if (prefix[i] == suffix[i])
answer++;
}
return answer;
}
// Driver Code
public static void Main (string[] args)
{
string s = "ababa";
Console.WriteLine(waysToSplit(s));
}
}
// This code is contributed by Yash_R
输出:
2
时间复杂度: O(N)
辅助空间: O(N)