给定一个大小为n的数组arr[]仅包含 0 和 1。问题是计算具有相同数量的 0 和 1 的子数组。
例子:
Input : arr[] = {1, 0, 0, 1, 0, 1, 1}
Output : 8
The index range for the 8 sub-arrays are:
(0, 1), (2, 3), (0, 3), (3, 4), (4, 5)
(2, 5), (0, 5), (1, 6)
该问题与具有相同数量的 0 和 1 的最大子阵列密切相关。
方法:以下是步骤:
- 将 arr[] 中的所有 0 视为 -1。
- 创建一个哈希表,保存每个sum[i]值的计数,其中 sum[i] = sum(arr[0]+..+arr[i]),对于 i = 0 到 n-1。
- 现在开始计算累积总和,然后我们得到该总和的增量计数 1,表示为哈希表中的索引。累积和中具有相同值的每对位置的数组构成具有相等数量的 1 和 0 的连续范围。
- 现在遍历哈希表,得到哈希表中每个元素出现的频率。让频率表示为freq 。对于每个freq > 1,我们可以通过(freq * (freq – 1)) / 2种方式选择子数组的任意两对索引。对所有freq执行相同操作并总结结果将是所有可能的包含相同数量 1 和 0 的子数组的数量。
- 此外,将 0 之和的频率添加到哈希表中以获得最终结果。
解释:
将所有 0 视为 -1,如果 sum[i] == sum[j],其中 sum[i] = sum(arr[0]+..+arr[i]) 和 sum[j] = sum(arr[ 0]+..+arr[j]) 并且 ‘i’ 小于 ‘j’,那么 sum(arr[i+1]+..+arr[j]) 必须是 0。它只能是 0 如果arr(i+1, .., j) 包含相等数量的 1 和 0。
C++
// C++ implementation to count subarrays with
// equal number of 1's and 0's
#include
using namespace std;
// function to count subarrays with
// equal number of 1's and 0's
int countSubarrWithEqualZeroAndOne(int arr[], int n)
{
// 'um' implemented as hash table to store
// frequency of values obtained through
// cumulative sum
unordered_map um;
int curr_sum = 0;
// Traverse original array and compute cumulative
// sum and increase count by 1 for this sum
// in 'um'. Adds '-1' when arr[i] == 0
for (int i = 0; i < n; i++) {
curr_sum += (arr[i] == 0) ? -1 : arr[i];
um[curr_sum]++;
}
int count = 0;
// traverse the hash table 'um'
for (auto itr = um.begin(); itr != um.end(); itr++) {
// If there are more than one prefix subarrays
// with a particular sum
if (itr->second > 1)
count += ((itr->second * (itr->second - 1)) / 2);
}
// add the subarrays starting from 1st element and
// have equal number of 1's and 0's
if (um.find(0) != um.end())
count += um[0];
// required count of subarrays
return count;
}
// Driver program to test above
int main()
{
int arr[] = { 1, 0, 0, 1, 0, 1, 1 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Count = "
<< countSubarrWithEqualZeroAndOne(arr, n);
return 0;
}
Java
// Java implementation to count subarrays with
// equal number of 1's and 0's
import java.util.*;
class GFG
{
// function to count subarrays with
// equal number of 1's and 0's
static int countSubarrWithEqualZeroAndOne(int arr[], int n)
{
// 'um' implemented as hash table to store
// frequency of values obtained through
// cumulative sum
Map um = new HashMap<>();
int curr_sum = 0;
// Traverse original array and compute cumulative
// sum and increase count by 1 for this sum
// in 'um'. Adds '-1' when arr[i] == 0
for (int i = 0; i < n; i++) {
curr_sum += (arr[i] == 0) ? -1 : arr[i];
um.put(curr_sum, um.get(curr_sum)==null?1:um.get(curr_sum)+1);
}
int count = 0;
// traverse the hash table 'um'
for (Map.Entry itr : um.entrySet())
{
// If there are more than one prefix subarrays
// with a particular sum
if (itr.getValue() > 1)
count += ((itr.getValue()* (itr.getValue()- 1)) / 2);
}
// add the subarrays starting from 1st element and
// have equal number of 1's and 0's
if (um.containsKey(0))
count += um.get(0);
// required count of subarrays
return count;
}
// Driver program to test above
public static void main(String[] args)
{
int arr[] = { 1, 0, 0, 1, 0, 1, 1 };
int n = arr.length;
System.out.println("Count = "
+ countSubarrWithEqualZeroAndOne(arr, n));
}
}
// This code is contributed by Rajput-Ji
Python3
# Python3 implementation to count
# subarrays with equal number
# of 1's and 0's
# function to count subarrays with
# equal number of 1's and 0's
def countSubarrWithEqualZeroAndOne (arr, n):
# 'um' implemented as hash table
# to store frequency of values
# obtained through cumulative sum
um = dict()
curr_sum = 0
# Traverse original array and compute
# cumulative sum and increase count
# by 1 for this sum in 'um'.
# Adds '-1' when arr[i] == 0
for i in range(n):
curr_sum += (-1 if (arr[i] == 0) else arr[i])
if um.get(curr_sum):
um[curr_sum]+=1
else:
um[curr_sum]=1
count = 0
# traverse the hash table 'um'
for itr in um:
# If there are more than one
# prefix subarrays with a
# particular sum
if um[itr] > 1:
count += ((um[itr] * int(um[itr] - 1)) / 2)
# add the subarrays starting from
# 1st element and have equal
# number of 1's and 0's
if um.get(0):
count += um[0]
# required count of subarrays
return int(count)
# Driver code to test above
arr = [ 1, 0, 0, 1, 0, 1, 1 ]
n = len(arr)
print("Count =",
countSubarrWithEqualZeroAndOne(arr, n))
# This code is contributed by "Sharad_Bhardwaj".
C#
// C# implementation to count subarrays
// with equal number of 1's and 0's
using System;
using System.Collections.Generic;
class GFG
{
// function to count subarrays with
// equal number of 1's and 0's
static int countSubarrWithEqualZeroAndOne(int []arr,
int n)
{
// 'um' implemented as hash table to store
// frequency of values obtained through
// cumulative sum
Dictionary mp = new Dictionary();
int curr_sum = 0;
// Traverse original array and compute cumulative
// sum and increase count by 1 for this sum
// in 'um'. Adds '-1' when arr[i] == 0
for (int i = 0; i < n; i++)
{
curr_sum += (arr[i] == 0) ? -1 : arr[i];
if(mp.ContainsKey(curr_sum))
{
var v = mp[curr_sum];
mp.Remove(curr_sum);
mp.Add(curr_sum, ++v);
}
else
mp.Add(curr_sum, 1);
}
int count = 0;
// traverse the hash table 'um'
foreach(KeyValuePair itr in mp)
{
// If there are more than one prefix subarrays
// with a particular sum
if (itr.Value > 1)
count += ((itr.Value* (itr.Value - 1)) / 2);
}
// add the subarrays starting from 1st element
// and have equal number of 1's and 0's
if (mp.ContainsKey(0))
count += mp[0];
// required count of subarrays
return count;
}
// Driver program to test above
public static void Main(String[] args)
{
int []arr = { 1, 0, 0, 1, 0, 1, 1 };
int n = arr.Length;
Console.WriteLine("Count = " +
countSubarrWithEqualZeroAndOne(arr, n));
}
}
// This code is contributed by PrinciRaj1992
Javascript
C++
#include
using namespace std;
int countSubarrWithEqualZeroAndOne(int arr[], int n){
map mp;
int sum=0;
int count=0;
for (int i = 0; i < n; i++) {
//Replacing 0's in array with -1
if (arr[i] == 0)
arr[i] = -1;
sum += arr[i];
//If sum = 0, it implies number of 0's and 1's are
//equal from arr[0]..arr[i]
if (sum == 0)
count++;
if (mp[sum])
count += mp[sum];
if(mp[sum]==0)
mp[sum]=1;
else
mp[sum]++;
}
return count;
}
int main()
{
int arr[] = {1, 0, 0, 1, 0, 1, 1};
int n = sizeof(arr)/sizeof(arr[0]);
cout<<"count="<
Java
import java.util.HashMap;
import java.util.Map;
// Java implementation to count subarrays with
// equal number of 1's and 0's
public class Main {
// Function that returns count of sub arrays
// with equal numbers of 1's and 0's
static int countSubarrWithEqualZeroAndOne(int[] arr, int n) {
Map myMap = new HashMap<>();
int sum = 0;
int count = 0;
for (int i = 0; i < n; i++) {
//Replacing 0's in array with -1
if (arr[i] == 0)
arr[i] = -1;
sum += arr[i];
//If sum = 0, it implies number of 0's and 1's are
//equal from arr[0]..arr[i]
if (sum == 0)
count++;
if (myMap.containsKey(sum))
count += myMap.get(sum);
if (!myMap.containsKey(sum))
myMap.put(sum, 1);
else
myMap.put(sum, myMap.get(sum) + 1);
}
return count;
}
// main function
public static void main(String[] args) {
int arr[] = { 1, 0, 0, 1, 0, 1, 1 };
int n = arr.length;
System.out.println("Count = " +
countSubarrWithEqualZeroAndOne(arr, n));
}
}
Python3
# Python3 implementation to count subarrays
# with equal number of 1's and 0's
def countSubarrWithEqualZeroAndOne(arr, n):
mp = dict()
Sum = 0
count = 0
for i in range(n):
# Replacing 0's in array with -1
if (arr[i] == 0):
arr[i] = -1
Sum += arr[i]
# If Sum = 0, it implies number of
# 0's and 1's are equal from arr[0]..arr[i]
if (Sum == 0):
count+=1
if (Sum in mp.keys()):
count += mp[Sum]
mp[Sum] = mp.get(Sum, 0) + 1
return count
# Driver Code
arr = [1, 0, 0, 1, 0, 1, 1]
n = len(arr)
print("count =",
countSubarrWithEqualZeroAndOne(arr, n))
# This code is contributed by mohit kumar
C#
// C# implementation to count subarrays with
// equal number of 1's and 0's
using System;
using System.Collections.Generic;
class GFG
{
// Function that returns count of sub arrays
// with equal numbers of 1's and 0's
static int countSubarrWithEqualZeroAndOne(int[] arr, int n)
{
Dictionary myMap = new Dictionary();
int sum = 0;
int count = 0;
for (int i = 0; i < n; i++)
{
//Replacing 0's in array with -1
if (arr[i] == 0)
arr[i] = -1;
sum += arr[i];
//If sum = 0, it implies number of 0's and 1's are
//equal from arr[0]..arr[i]
if (sum == 0)
count++;
if (myMap.ContainsKey(sum))
count += myMap[sum];
if (!myMap.ContainsKey(sum))
myMap.Add(sum, 1);
else{
var v= myMap[sum]+1;
myMap.Remove(sum);
myMap.Add(sum, v);
}
}
return count;
}
// Driver code
public static void Main(String[] args)
{
int []arr = { 1, 0, 0, 1, 0, 1, 1 };
int n = arr.Length;
Console.WriteLine("Count = " +
countSubarrWithEqualZeroAndOne(arr, n));
}
}
// This code is contributed by 29AjayKumar
Javascript
输出:
Count = 8
时间复杂度: O(n)。
辅助空间: O(n)。
另一种方法:
C++
#include
using namespace std;
int countSubarrWithEqualZeroAndOne(int arr[], int n){
map mp;
int sum=0;
int count=0;
for (int i = 0; i < n; i++) {
//Replacing 0's in array with -1
if (arr[i] == 0)
arr[i] = -1;
sum += arr[i];
//If sum = 0, it implies number of 0's and 1's are
//equal from arr[0]..arr[i]
if (sum == 0)
count++;
if (mp[sum])
count += mp[sum];
if(mp[sum]==0)
mp[sum]=1;
else
mp[sum]++;
}
return count;
}
int main()
{
int arr[] = {1, 0, 0, 1, 0, 1, 1};
int n = sizeof(arr)/sizeof(arr[0]);
cout<<"count="<
Java
import java.util.HashMap;
import java.util.Map;
// Java implementation to count subarrays with
// equal number of 1's and 0's
public class Main {
// Function that returns count of sub arrays
// with equal numbers of 1's and 0's
static int countSubarrWithEqualZeroAndOne(int[] arr, int n) {
Map myMap = new HashMap<>();
int sum = 0;
int count = 0;
for (int i = 0; i < n; i++) {
//Replacing 0's in array with -1
if (arr[i] == 0)
arr[i] = -1;
sum += arr[i];
//If sum = 0, it implies number of 0's and 1's are
//equal from arr[0]..arr[i]
if (sum == 0)
count++;
if (myMap.containsKey(sum))
count += myMap.get(sum);
if (!myMap.containsKey(sum))
myMap.put(sum, 1);
else
myMap.put(sum, myMap.get(sum) + 1);
}
return count;
}
// main function
public static void main(String[] args) {
int arr[] = { 1, 0, 0, 1, 0, 1, 1 };
int n = arr.length;
System.out.println("Count = " +
countSubarrWithEqualZeroAndOne(arr, n));
}
}
蟒蛇3
# Python3 implementation to count subarrays
# with equal number of 1's and 0's
def countSubarrWithEqualZeroAndOne(arr, n):
mp = dict()
Sum = 0
count = 0
for i in range(n):
# Replacing 0's in array with -1
if (arr[i] == 0):
arr[i] = -1
Sum += arr[i]
# If Sum = 0, it implies number of
# 0's and 1's are equal from arr[0]..arr[i]
if (Sum == 0):
count+=1
if (Sum in mp.keys()):
count += mp[Sum]
mp[Sum] = mp.get(Sum, 0) + 1
return count
# Driver Code
arr = [1, 0, 0, 1, 0, 1, 1]
n = len(arr)
print("count =",
countSubarrWithEqualZeroAndOne(arr, n))
# This code is contributed by mohit kumar
C#
// C# implementation to count subarrays with
// equal number of 1's and 0's
using System;
using System.Collections.Generic;
class GFG
{
// Function that returns count of sub arrays
// with equal numbers of 1's and 0's
static int countSubarrWithEqualZeroAndOne(int[] arr, int n)
{
Dictionary myMap = new Dictionary();
int sum = 0;
int count = 0;
for (int i = 0; i < n; i++)
{
//Replacing 0's in array with -1
if (arr[i] == 0)
arr[i] = -1;
sum += arr[i];
//If sum = 0, it implies number of 0's and 1's are
//equal from arr[0]..arr[i]
if (sum == 0)
count++;
if (myMap.ContainsKey(sum))
count += myMap[sum];
if (!myMap.ContainsKey(sum))
myMap.Add(sum, 1);
else{
var v= myMap[sum]+1;
myMap.Remove(sum);
myMap.Add(sum, v);
}
}
return count;
}
// Driver code
public static void Main(String[] args)
{
int []arr = { 1, 0, 0, 1, 0, 1, 1 };
int n = arr.Length;
Console.WriteLine("Count = " +
countSubarrWithEqualZeroAndOne(arr, n));
}
}
// This code is contributed by 29AjayKumar
Javascript
输出:
Count = 8
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。