给定二进制字符串str ,任务是计算将给定字符串分成三个具有相同0数的非重叠子字符串的方法总数。
例子:
Input: str = “01010”
Output: 4
Explanation:
The possible splits are: [0, 10, 10], [01, 01, 0], [01, 0, 10], [0, 101, 0]
Input: str = “11111”
Output: 0
方法:解决问题的思路是使用Hashing的概念。以下是解决问题的步骤:
- 遍历字符串并计算零的总数并将其存储在变量中,例如total_count 。
- 使用 Hashmap,比如map ,来存储 0 的累积和的频率。
- 用total_count/3初始化变量k ,它表示每个分区中所需的0数量。
- 初始化变量res和sum分别存储分割字符串的方式数和0 s 的累积和。
- 如果当前字符为0 ,则迭代给定的字符串并递增sum 。
- 通过map[k]增加res ,如果sum = 2k并且k存在于地图上。
- 更新地图中总和的频率。
- 最后返回res 。
- 如果total_count不能被3整除,则返回 0。
下面是上述方法的实现:
C++
// C++ implementation for the above approach
#include
using namespace std;
// Function to return ways to split
// a string into three parts
// with the equal number of 0
int count(string s)
{
// Store total count of 0s
int cnt = 0;
// Count total no. of 0s
// character in given string
for(char c : s)
{
cnt += c == '0' ? 1 : 0;
}
// If total count of 0
// character is not
// divisible by 3
if (cnt % 3 != 0)
return 0;
int res = 0, k = cnt / 3, sum = 0;
// Initialize mp to store
// frequency of k
map mp;
// Traverse string to find
// ways to split string
for(int i = 0; i < s.length(); i++)
{
// Increment count if 0 appears
sum += s[i] == '0' ? 1 : 0;
// Increment result if sum equal to
// 2*k and k exists in mp
if (sum == 2 * k && mp.find(k) != mp.end() &&
i < s.length() - 1 && i > 0)
{
res += mp[k];
}
// Insert sum in mp
mp[sum]++;
}
// Return result
return res;
}
// Driver Code
int main()
{
// Given string
string str = "01010";
// Function call
cout << count(str);
}
// This code is contributed by rutvik_56
Java
// Java implementation for the above approach
import java.util.*;
import java.lang.*;
class GFG {
// Function to return ways to split
// a string into three parts
// with the equal number of 0
static int count(String s)
{
// Store total count of 0s
int cnt = 0;
// Count total no. of 0s
// character in given string
for (char c : s.toCharArray()) {
cnt += c == '0' ? 1 : 0;
}
// If total count of 0
// character is not
// divisible by 3
if (cnt % 3 != 0)
return 0;
int res = 0, k = cnt / 3, sum = 0;
// Initialize map to store
// frequency of k
Map map = new HashMap<>();
// Traverse string to find
// ways to split string
for (int i = 0; i < s.length(); i++) {
// Increment count if 0 appears
sum += s.charAt(i) == '0' ? 1 : 0;
// Increment result if sum equal to
// 2*k and k exists in map
if (sum == 2 * k && map.containsKey(k)
&& i < s.length() - 1 && i > 0) {
res += map.get(k);
}
// Insert sum in map
map.put(sum,
map.getOrDefault(sum, 0) + 1);
}
// Return result
return res;
}
// Driver Code
public static void main(String[] args)
{
// Given string
String str = "01010";
// Function call
System.out.println(count(str));
}
}
Python3
# Python3 implementation for
# the above approach
# Function to return ways to split
# a string into three parts
# with the equal number of 0
def count(s):
# Store total count of 0s
cnt = 0
# Count total no. of 0s
# character in given string
for c in s:
if c == '0':
cnt += 1
# If total count of 0
# character is not
# divisible by 3
if (cnt % 3 != 0):
return 0
res = 0
k = cnt // 3
sum = 0
# Initialize map to store
# frequency of k
mp = {}
# Traverse string to find
# ways to split string
for i in range(len(s)):
# Increment count if 0 appears
if s[i] == '0':
sum += 1
# Increment result if sum equal to
# 2*k and k exists in map
if (sum == 2 * k and k in mp and
i < len(s) - 1 and i > 0):
res += mp[k]
# Insert sum in map
if sum in mp:
mp[sum] += 1
else:
mp[sum] = 1
# Return result
return res
# Driver Code
if __name__ == "__main__":
# Given string
st = "01010"
# Function call
print(count(st))
# This code is contributed by Chitranayal
C#
// C# implementation for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to return ways to split
// a string into three parts
// with the equal number of 0
static int count(String s)
{
// Store total count of 0s
int cnt = 0;
// Count total no. of 0s
// character in given string
foreach(char c in s.ToCharArray())
{
cnt += c == '0' ? 1 : 0;
}
// If total count of 0
// character is not
// divisible by 3
if (cnt % 3 != 0)
return 0;
int res = 0, k = cnt / 3, sum = 0;
// Initialize map to store
// frequency of k
Dictionary map = new Dictionary();
// Traverse string to find
// ways to split string
for(int i = 0; i < s.Length; i++)
{
// Increment count if 0 appears
sum += s[i] == '0' ? 1 : 0;
// Increment result if sum equal to
// 2*k and k exists in map
if (sum == 2 * k && map.ContainsKey(k) &&
i < s.Length - 1 && i > 0)
{
res += map[k];
}
// Insert sum in map
if(map.ContainsKey(sum))
map[sum] = map[sum] + 1;
else
map.Add(sum, 1);
}
// Return result
return res;
}
// Driver Code
public static void Main(String[] args)
{
// Given string
String str = "01010";
// Function call
Console.WriteLine(count(str));
}
}
// This code is contributed by Amit Katiyar
Javascript
C++
// C++ program for above approach
#include
using namespace std;
// Function to calculate
// the number of ways to split
int splitstring(string s)
{
int n = s.length();
// Calculating the total
// number of zeros
int zeros = 0;
for (int i = 0; i < n; i++)
if (s[i] == '0')
zeros++;
// Case1
// If total count of zeros is not
// divisible by 3
if (zeros % 3 != 0)
return 0;
// Case2
// if total count of zeros
// is zero
if (zeros == 0)
return ((n - 1) * (n - 2)) / 2;
// Case3
// General case
// Number of zeros in each substring
int zerosInEachSubstring = zeros / 3;
// Initialising zero to the number of ways
// for first and second cut
int waysOfFirstCut = 0, waysOfSecondCut = 0;
// Initializing the count
int count = 0;
// Traversing from the beginning
for (int i = 0; i < n; i++)
{
// Incrementing the count
// if the element is '0'
if (s[i] == '0')
count++;
// Incrementing the ways for the
// 1st cut if count is equal to
// zeros required in each substring
if (count == zerosInEachSubstring)
waysOfFirstCut++;
// Incrementing the ways for the
// 2nd cut if count is equal to
// 2*(zeros required in each substring)
else if (count == 2 * zerosInEachSubstring)
waysOfSecondCut++;
}
// Total number of ways to split is
// multiplication of ways for the 1st
// and 2nd cut
return waysOfFirstCut * waysOfSecondCut;
}
// Driver Code
int main()
{
string s = "01010";
// Function Call
cout << "The number of ways to split is "
<< splitstring(s) << endl;
}
// this code is contributed by Arif
Java
// Java program for above approach
import java.util.*;
class GFG{
// Function to calculate
// the number of ways to split
static int splitstring(String s)
{
int n = s.length();
// Calculating the total
// number of zeros
int zeros = 0;
for(int i = 0; i < n; i++)
if (s.charAt(i) == '0')
zeros++;
// Case1
// If total count of zeros is not
// divisible by 3
if (zeros % 3 != 0)
return 0;
// Case2
// if total count of zeros
// is zero
if (zeros == 0)
return ((n - 1) * (n - 2)) / 2;
// Case3
// General case
// Number of zeros in each substring
int zerosInEachSubstring = zeros / 3;
// Initialising zero to the number of ways
// for first and second cut
int waysOfFirstCut = 0;
int waysOfSecondCut = 0;
// Initializing the count
int count = 0;
// Traversing from the beginning
for(int i = 0; i < n; i++)
{
// Incrementing the count
// if the element is '0'
if (s.charAt(i) == '0')
count++;
// Incrementing the ways for the
// 1st cut if count is equal to
// zeros required in each substring
if (count == zerosInEachSubstring)
waysOfFirstCut++;
// Incrementing the ways for the
// 2nd cut if count is equal to
// 2*(zeros required in each substring)
else if (count == 2 * zerosInEachSubstring)
waysOfSecondCut++;
}
// Total number of ways to split is
// multiplication of ways for the 1st
// and 2nd cut
return waysOfFirstCut * waysOfSecondCut;
}
// Driver Code
public static void main(String args[])
{
String s = "01010";
// Function Call
System.out.println("The number of " +
"ways to split is " +
splitstring(s));
}
}
// This code is contributed by Stream_Cipher
Python3
# Python3 program for above approach
# Function to calculate
# the number of ways to split
def splitstring(s):
n = len(s)
# Calculating the total
# number of zeros
zeros = 0
for i in range(n):
if s[i] == '0':
zeros += 1
# Case1
# If total count of zeros is not
# divisible by 3
if zeros % 3 != 0:
return 0
# Case2
# if total count of zeros
# is zero
if zeros == 0:
return ((n - 1) *
(n - 2)) // 2
# Case3
# General case
# Number of zeros in each substring
zerosInEachSubstring = zeros // 3
# Initialising zero to the number of ways
# for first and second cut
waysOfFirstCut, waysOfSecondCut = 0, 0
# Initializing the count
count = 0
# Traversing from the beginning
for i in range(n):
# Incrementing the count
# if the element is '0'
if s[i] == '0':
count += 1
# Incrementing the ways for the
# 1st cut if count is equal to
# zeros required in each substring
if (count == zerosInEachSubstring):
waysOfFirstCut += 1
# Incrementing the ways for the
# 2nd cut if count is equal to
# 2*(zeros required in each substring)
elif (count == 2 * zerosInEachSubstring):
waysOfSecondCut += 1
# Total number of ways to split is
# multiplication of ways for the 1st
# and 2nd cut
return waysOfFirstCut * waysOfSecondCut
# Driver code
s = "01010"
# Function call
print("The number of ways to split is", splitstring(s))
# This code is contributed by divyeshrabadiya07
C#
// C# program for above approach
using System.Collections.Generic;
using System;
class GFG{
// Function to calculate
// the number of ways to split
static int splitstring(string s)
{
int n = s.Length;
// Calculating the total
// number of zeros
int zeros = 0;
for(int i = 0; i < n; i++)
if (s[i] == '0')
zeros++;
// Case1
// If total count of zeros is not
// divisible by 3
if (zeros % 3 != 0)
return 0;
// Case2
// if total count of zeros
// is zero
if (zeros == 0)
return ((n - 1) * (n - 2)) / 2;
// Case3
// General case
// Number of zeros in each substring
int zerosInEachSubstring = zeros / 3;
// Initialising zero to the number of ways
// for first and second cut
int waysOfFirstCut = 0;
int waysOfSecondCut = 0;
// Initializing the count
int count = 0;
// Traversing from the beginning
for(int i = 0; i < n; i++)
{
// Incrementing the count
// if the element is '0'
if (s[i] == '0')
count++;
// Incrementing the ways for the
// 1st cut if count is equal to
// zeros required in each substring
if (count == zerosInEachSubstring)
waysOfFirstCut++;
// Incrementing the ways for the
// 2nd cut if count is equal to
// 2*(zeros required in each substring)
else if (count == 2 * zerosInEachSubstring)
waysOfSecondCut++;
}
// Total number of ways to split is
// multiplication of ways for the 1st
// and 2nd cut
return waysOfFirstCut * waysOfSecondCut;
}
// Driver Code
public static void Main()
{
string s = "01010";
// Function call
Console.WriteLine("The number of ways " +
"to split is " +
splitstring(s));
}
}
// This code is contributed by Stream_Cipher
Javascript
输出
4
时间复杂度: O(N)
辅助空间: O(N)
有效的方法:
为了将输入字符串分成三部分,只需要两次切割,将得到三个子字符串-S1、S2 和 S3。每个子串将有相同数量的 0,即(0 的总数)/3。现在从字符串的开头跟踪 0 的数量。一旦计数等于(0 的总数)/3,进行第一次切割。同样,一旦 0 的计数等于 2*(1 的总数)/3,则进行第二次切割。
算法
- 计算 0 的数量。如果不能被 3 整除,则 answer=0。
- 如果计数为 0,则每个子串将具有相同数量的“0”,即零个“0”。因此,分割给定字符串的方法总数是从n-1 个位置中选择 2 个位置来分割字符串的组合数。对于第一个选择,我们有 n-1 个选择,对于第二个选择,我们有 n-2 个选择。因此,组合的总数为(n-1)*(n-2)。由于选择是相同的,因此将其除以 2 的阶乘。所以 answer= ((n-1)*(n-2))/2。
- 从头开始遍历给定的字符串,再次计数“0”的个数,如果计数达到(“0”的总数)/3,则开始累加第1次切割的路数;当计数达到 2*(‘0s’ 的总数)/3 时,我们开始累积第二次切割的路数。
- 答案是第 1 次切割和第 2 次切割的方式数的乘积。
下面是上述方法的实现:
C++
// C++ program for above approach
#include
using namespace std;
// Function to calculate
// the number of ways to split
int splitstring(string s)
{
int n = s.length();
// Calculating the total
// number of zeros
int zeros = 0;
for (int i = 0; i < n; i++)
if (s[i] == '0')
zeros++;
// Case1
// If total count of zeros is not
// divisible by 3
if (zeros % 3 != 0)
return 0;
// Case2
// if total count of zeros
// is zero
if (zeros == 0)
return ((n - 1) * (n - 2)) / 2;
// Case3
// General case
// Number of zeros in each substring
int zerosInEachSubstring = zeros / 3;
// Initialising zero to the number of ways
// for first and second cut
int waysOfFirstCut = 0, waysOfSecondCut = 0;
// Initializing the count
int count = 0;
// Traversing from the beginning
for (int i = 0; i < n; i++)
{
// Incrementing the count
// if the element is '0'
if (s[i] == '0')
count++;
// Incrementing the ways for the
// 1st cut if count is equal to
// zeros required in each substring
if (count == zerosInEachSubstring)
waysOfFirstCut++;
// Incrementing the ways for the
// 2nd cut if count is equal to
// 2*(zeros required in each substring)
else if (count == 2 * zerosInEachSubstring)
waysOfSecondCut++;
}
// Total number of ways to split is
// multiplication of ways for the 1st
// and 2nd cut
return waysOfFirstCut * waysOfSecondCut;
}
// Driver Code
int main()
{
string s = "01010";
// Function Call
cout << "The number of ways to split is "
<< splitstring(s) << endl;
}
// this code is contributed by Arif
Java
// Java program for above approach
import java.util.*;
class GFG{
// Function to calculate
// the number of ways to split
static int splitstring(String s)
{
int n = s.length();
// Calculating the total
// number of zeros
int zeros = 0;
for(int i = 0; i < n; i++)
if (s.charAt(i) == '0')
zeros++;
// Case1
// If total count of zeros is not
// divisible by 3
if (zeros % 3 != 0)
return 0;
// Case2
// if total count of zeros
// is zero
if (zeros == 0)
return ((n - 1) * (n - 2)) / 2;
// Case3
// General case
// Number of zeros in each substring
int zerosInEachSubstring = zeros / 3;
// Initialising zero to the number of ways
// for first and second cut
int waysOfFirstCut = 0;
int waysOfSecondCut = 0;
// Initializing the count
int count = 0;
// Traversing from the beginning
for(int i = 0; i < n; i++)
{
// Incrementing the count
// if the element is '0'
if (s.charAt(i) == '0')
count++;
// Incrementing the ways for the
// 1st cut if count is equal to
// zeros required in each substring
if (count == zerosInEachSubstring)
waysOfFirstCut++;
// Incrementing the ways for the
// 2nd cut if count is equal to
// 2*(zeros required in each substring)
else if (count == 2 * zerosInEachSubstring)
waysOfSecondCut++;
}
// Total number of ways to split is
// multiplication of ways for the 1st
// and 2nd cut
return waysOfFirstCut * waysOfSecondCut;
}
// Driver Code
public static void main(String args[])
{
String s = "01010";
// Function Call
System.out.println("The number of " +
"ways to split is " +
splitstring(s));
}
}
// This code is contributed by Stream_Cipher
蟒蛇3
# Python3 program for above approach
# Function to calculate
# the number of ways to split
def splitstring(s):
n = len(s)
# Calculating the total
# number of zeros
zeros = 0
for i in range(n):
if s[i] == '0':
zeros += 1
# Case1
# If total count of zeros is not
# divisible by 3
if zeros % 3 != 0:
return 0
# Case2
# if total count of zeros
# is zero
if zeros == 0:
return ((n - 1) *
(n - 2)) // 2
# Case3
# General case
# Number of zeros in each substring
zerosInEachSubstring = zeros // 3
# Initialising zero to the number of ways
# for first and second cut
waysOfFirstCut, waysOfSecondCut = 0, 0
# Initializing the count
count = 0
# Traversing from the beginning
for i in range(n):
# Incrementing the count
# if the element is '0'
if s[i] == '0':
count += 1
# Incrementing the ways for the
# 1st cut if count is equal to
# zeros required in each substring
if (count == zerosInEachSubstring):
waysOfFirstCut += 1
# Incrementing the ways for the
# 2nd cut if count is equal to
# 2*(zeros required in each substring)
elif (count == 2 * zerosInEachSubstring):
waysOfSecondCut += 1
# Total number of ways to split is
# multiplication of ways for the 1st
# and 2nd cut
return waysOfFirstCut * waysOfSecondCut
# Driver code
s = "01010"
# Function call
print("The number of ways to split is", splitstring(s))
# This code is contributed by divyeshrabadiya07
C#
// C# program for above approach
using System.Collections.Generic;
using System;
class GFG{
// Function to calculate
// the number of ways to split
static int splitstring(string s)
{
int n = s.Length;
// Calculating the total
// number of zeros
int zeros = 0;
for(int i = 0; i < n; i++)
if (s[i] == '0')
zeros++;
// Case1
// If total count of zeros is not
// divisible by 3
if (zeros % 3 != 0)
return 0;
// Case2
// if total count of zeros
// is zero
if (zeros == 0)
return ((n - 1) * (n - 2)) / 2;
// Case3
// General case
// Number of zeros in each substring
int zerosInEachSubstring = zeros / 3;
// Initialising zero to the number of ways
// for first and second cut
int waysOfFirstCut = 0;
int waysOfSecondCut = 0;
// Initializing the count
int count = 0;
// Traversing from the beginning
for(int i = 0; i < n; i++)
{
// Incrementing the count
// if the element is '0'
if (s[i] == '0')
count++;
// Incrementing the ways for the
// 1st cut if count is equal to
// zeros required in each substring
if (count == zerosInEachSubstring)
waysOfFirstCut++;
// Incrementing the ways for the
// 2nd cut if count is equal to
// 2*(zeros required in each substring)
else if (count == 2 * zerosInEachSubstring)
waysOfSecondCut++;
}
// Total number of ways to split is
// multiplication of ways for the 1st
// and 2nd cut
return waysOfFirstCut * waysOfSecondCut;
}
// Driver Code
public static void Main()
{
string s = "01010";
// Function call
Console.WriteLine("The number of ways " +
"to split is " +
splitstring(s));
}
}
// This code is contributed by Stream_Cipher
Javascript
输出
The number of ways to split is 4
时间复杂度:O(n)
空间复杂度:O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。