Open In App

Find the maximum number of indices having 0 as Prefix sum

Last Updated : 19 Sep, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[]. Find the maximum number of indices having 0 as prefix sums possible by replacing the 0s in the array with any arbitrary value.

Examples:

Input: arr[] = {2, 0, 1, -1, 0}
Output: 3
Explanation: On changing the 1st 0 at arr[1] to -2 the array changes to {2, -2, 1, -1, 0} which 3 prefix sums equal to 0 at index 1, 3, and 4.

Input: arr[] = {0, 0, 0, 0}
Output: 4
Explanation: There are 4 indices where the prefix sum is 0.

Approach:  This can be solved using the following idea:

  • The idea is that changing the element whose value is 0 will impact the prefix sums later than that index. 
  • So first, we find the subarrays starting with 0 and change the 0 in such a way that it makes 0 prefix sums for later that index because if they’re more frequent elements with the same prefix sums, after changing 0’s to inverted values of most frequent prefix sums after that 0, the zero prefix sums can be maximized.
  • So we take the prefix sum and find the most frequent prefix sum after 0 of every subarray starting with 0 and add the frequency to the answer.

Follow the steps mentioned below to solve the problem:

  • Initialize the arrays say prefix_sum to store the prefix sum and the array endmark to the mark array to mark the end of the subarray starting with 0.
  • Initialize the variables flag to check whether 0 has occurred before and max_freq to store the maximum frequency of prefix sums of each subarray and res to store max possible 0 prefix sums.
  • Traverse through the array and mark the end of the subarray starting with 0.
  • Build the prefix sum array of the array arr[]
  • Initialize a map freq to store the frequencies
  • Iterate through the array and add the frequency of the most frequent prefix sum of each subarray starting with 0 to the res.
  • Check if the endmark of that index is false and keep the frequency of prefix sum at that index increasing.
  • Else add the maximum frequent prefix sum to the res.
  • Return the res.

Below is the implementation for the above approach:

C++




// C++ code for the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to find maximum 0 prefix sums
// after replacing 0's
int findmax_zeroprefixes(int arr[], int n)
{
  
    // Initialize the arrays say prefix_sum
    // to store the prefix sum and the array
    // end mark to the mark array to mark
    // the end of subarray starting with 0.
    int prefix_sum[n];
  
    bool endmark[n];
  
    // Initialize the variables flag to
    // check whether 0 as occurred before
    // and max_freq to store the maximum
    // frequency of prefix sums of each
    // subarray and res to store max
    // possible 0 prefix sums.
    bool flag = 0;
    int max_freq = 0;
    int res = 0;
  
    if (arr[0] == 0) {
        flag = 1;
    }
  
    // Traverse through the array and mark
    // the end of subarray starting with 0.
    for (int i = 0; i < n; i++) {
  
        if (i + 1 < n) {
            if (arr[i + 1] == 0) {
                endmark[i] = true;
            }
            else {
                endmark[i] = false;
            }
        }
        else {
            endmark[i] = true;
        }
    }
  
    // Build the prefix sum array
    // of the array arr[]
    prefix_sum[0] = arr[0];
  
    for (int i = 1; i < n; i++) {
        prefix_sum[i] = prefix_sum[i - 1] + arr[i];
    }
  
    res = 0;
  
    // Initialize a map  to store
    // the frequencies
    unordered_map<int, int> freq;
    max_freq = 0;
  
    // Iterate through the array and add
    // the frequency of most frequent
    // prefix sum  of each subarray
    // starting with 0 to the res.
    for (int i = 0; i < n; i++) {
  
        // If endmark of that index is false
        // keep the frequency of prefix sum
        // at that index increasing
        if (endmark[i] == false) {
  
            freq[prefix_sum[i]]++;
            max_freq = max(max_freq, freq[prefix_sum[i]]);
        }
  
        // Else add the maximum frequent
        // prefix sum to the res.
        else {
  
            freq[prefix_sum[i]]++;
            max_freq = max(max_freq, freq[prefix_sum[i]]);
  
            // For the first subarray whose
            // sum is 0
            if (flag == 0) {
  
                // Add the frequency of
                // zero prefixsums
                res = res + freq[0];
                max_freq = 0;
                freq.clear();
                flag = 1;
            }
            // For the remaining subarrays starting
            // with 0's
            else {
  
                // Add the max frequency
                res = res + max_freq;
                freq.clear();
                max_freq = 0;
            }
        }
    }
    // Return the res
    return res;
}
// Driver function
int main()
{
    int arr[] = { 2, 0, 1, -1, 0 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << findmax_zeroprefixes(arr, n) << endl;
}


Java




// Java code for the above approach
  
import java.io.*;
import java.util.*;
  
class GFG {
  
  // Function to find maximum 0 prefix sums
  // after replacing 0's
  public static int findmax_zeroprefixes(int[] arr, int n)
  {
  
    // Initialize the arrays say prefix_sum
    // to store the prefix sum and the array
    // end mark to the mark array to mark
    // the end of subarray starting with 0.
    int[] prefix_sum = new int[n];
    boolean[] endmark = new boolean[n];
  
    // Initialize the variables flag to
    // check whether 0 as occurred before
    // and max_freq to store the maximum
    // frequency of prefix sums of each
    // subarray and res to store max
    // possible 0 prefix sums.
    boolean flag = false;
    int max_freq = 0;
    int res = 0;
  
    if (arr[0] == 0) {
      flag = true;
    }
  
    // Traverse through the array and mark
    // the end of subarray starting with 0.
    for (int i = 0; i < n; i++) {
  
      if (i + 1 < n) {
        if (arr[i + 1] == 0) {
          endmark[i] = true;
        }
        else {
          endmark[i] = false;
        }
      }
      else {
        endmark[i] = true;
      }
    }
  
    // Build the prefix sum array
    // of the array arr[]
    prefix_sum[0] = arr[0];
  
    for (int i = 1; i < n; i++) {
      prefix_sum[i] = prefix_sum[i - 1] + arr[i];
    }
  
    res = 0;
  
    // Initialize a map  to store
    // the frequencies
    Map<Integer, Integer> freq = new HashMap<>();
    max_freq = 0;
  
    // Iterate through the array and add
    // the frequency of most frequent
    // prefix sum  of each subarray
    // starting with 0 to the res.
    for (int i = 0; i < n; i++) {
  
      // If endmark of that index is false
      // keep the frequency of prefix sum
      // at that index increasing
      if (endmark[i] == false) {
  
        freq.put(prefix_sum[i],
                 freq.getOrDefault(prefix_sum[i], 0)
                 + 1);
        max_freq = Math.max(
          max_freq, freq.get(prefix_sum[i]));
      }
  
      // Else add the maximum frequent
      // prefix sum to the res.
      else {
  
        freq.put(prefix_sum[i],
                 freq.getOrDefault(prefix_sum[i], 0)
                 + 1);
        max_freq = Math.max(
          max_freq, freq.get(prefix_sum[i]));
  
        // For the first subarray whose
        // sum is 0
        if (flag == false) {
  
          // Add the frequency of
          // zero prefixsums
          if (freq.containsKey(0))
            res = res + freq.get(0);
          max_freq = 0;
          freq.clear();
          flag = true;
        }
        // For the remaining subarrays starting
        // with 0's
        else {
  
          // Add the max frequency
          res = res + max_freq;
          freq.clear();
          max_freq = 0;
        }
      }
    }
    // Return the res
    return res;
  }
  
  public static void main(String[] args)
  {
    int[] arr = { 2, 0, 1, -1, 0 };
    int n = arr.length;
    System.out.println(findmax_zeroprefixes(arr, n));
  }
}
  
// This code is contributed by lokesh.


Python3




# Python code for the above approach
  
# Function to find maximum 0 prefix sums
# after replacing 0's
def findmax_zeroprefixes(arr,n):
    # Initialize the arrays say prefix_sum
    # to store the prefix sum and the array
    # end mark to the mark array to mark
    # the end of subarray starting with 0.
    prefix_sum=[0]*n
      
    endmark=[True]*n
      
    # Initialize the variables flag to
    # check whether 0 as occurred before
    # and max_freq to store the maximum
    # frequency of prefix sums of each
    # subarray and res to store max
    # possible 0 prefix sums.
    flag=0
    max_freq=0
    res=0
      
    if(arr[0]==0):
        flag=1
      
    # Traverse through the array and mark
    # the end of subarray starting with 0.
    for i in range(n):
        if(i+1<n):
            if(arr[i+1]==0):
                endmark[i]=True
            else:
                endmark[i]=False
        else:
            endmark[i]=True
      
    # Build the prefix sum array
    # of the array arr[]
    prefix_sum[0]=arr[0];
    for i in range(1,n):
        prefix_sum[i]=prefix_sum[i-1]+arr[i]
      
    res=0
      
    # Initialize a map to store
    # the frequencies
    freq={}
    max_freq=0
      
    # Iterate through the array and add
    # the frequency of most frequent
    # prefix sum of each subarray
    # starting with 0 to the res.
    for i in range(n):
        # If endmark of that index is false
        # keep the frequency of prefix sum
        # at that index increasing
        if(endmark[i]==False):
            if(prefix_sum[i] in freq):
                freq[prefix_sum[i]]=freq[prefix_sum[i]]+1
            else:
                freq[prefix_sum[i]]=1
            max_freq=max(max_freq,freq[prefix_sum[i]])
          
        # Else add the maximum frequent
        # prefix sum to the res.
        else:
            if(prefix_sum[i] in freq):
                freq[prefix_sum[i]]=freq[prefix_sum[i]]+1
            else:
                freq[prefix_sum[i]]=1
              
            max_freq=max(max_freq,freq[prefix_sum[i]])
              
            # For the first subarray whose
            # sum is 0
            if(flag==0):
                # Add the frequency of
                # zero prefixsums
                if(0 in freq):
                    res=res+freq[0]
                max_freq=0
                freq.clear()
                flag=1
            # For the remaining subarrays starting
            # with 0's
            else:
                # Add the max frequency
                res=res+max_freq
                freq.clear()
                max_freq=0
    # Return the res
    return res
      
# Driver function
arr=[2,0,1,-1,0]
n=len(arr)
print(findmax_zeroprefixes(arr,n))
  
# This code is contributed by Pushpesh Raj.


C#




// C# code for the above approach
using System;
using System.Collections.Generic;
  
public class GFG {
  
  // Function to find maximum 0 prefix sums
  // after replacing 0's
  public static int findmax_zeroprefixes(int[] arr, int n)
  {
    // Initialize the arrays say prefix_sum
    // to store the prefix sum and the array
    // end mark to the mark array to mark
    // the end of subarray starting with 0.
    int[] prefix_sum = new int[n];
    bool[] endmark = new bool[n];
  
    // Initialize the variables flag to
    // check whether 0 as occurred before
    // and max_freq to store the maximum
    // frequency of prefix sums of each
    // subarray and res to store max
    // possible 0 prefix sums.
    bool flag = false;
    int max_freq = 0;
    int res = 0;
  
    if (arr[0] == 0) {
      flag = true;
    }
  
    // Traverse through the array and mark
    // the end of subarray starting with 0.
    for (int i = 0; i < n; i++) {
      if (i + 1 < n) {
        if (arr[i + 1] == 0) {
          endmark[i] = true;
        }
        else {
          endmark[i] = false;
        }
      }
      else {
        endmark[i] = true;
      }
    }
  
    // Build the prefix sum array
    // of the array arr[]
    prefix_sum[0] = arr[0];
  
    for (int i = 1; i < n; i++) {
      prefix_sum[i] = prefix_sum[i - 1] + arr[i];
    }
  
    res = 0;
  
    // Initialize a map to store
    // the frequencies
    Dictionary<int, int> freq
      = new Dictionary<int, int>();
    max_freq = 0;
  
    // Iterate through the array and add
    // the frequency of most frequent
    // prefix sum of each subarray
    // starting with 0 to the res.
    for (int i = 0; i < n; i++) {
      // If endmark of that index is false
      // keep the frequency of prefix sum
      // at that index increasing
      if (endmark[i] == false) {
        if (!freq.ContainsKey(prefix_sum[i])) {
          freq.Add(prefix_sum[i], 1);
        }
        else {
          freq[prefix_sum[i]]++;
        }
        max_freq = Math.Max(max_freq,
                            freq[prefix_sum[i]]);
      }
  
      // Else add the maximum frequent
      // prefix sum to the res.
      else {
        if (!freq.ContainsKey(prefix_sum[i])) {
          freq.Add(prefix_sum[i], 1);
        }
        else {
          freq[prefix_sum[i]]++;
        }
        max_freq = Math.Max(max_freq,
                            freq[prefix_sum[i]]);
  
        // For the first subarray whose
        // sum is 0
        if (flag == false) {
          // Add the frequency of
          // zero prefixsums
          if (freq.ContainsKey(0)) {
            res = res + freq[0];
          }
          max_freq = 0;
          freq.Clear();
          flag = true;
        }
        // For the remaining subarrays starting
        // with 0's
        else {
          // Add the max frequency
          res = res + max_freq;
          freq.Clear();
          max_freq = 0;
        }
      }
    }
    // Return the res
    return res;
  }
  
  static public void Main()
  {
  
    // Code
    int[] arr = { 2, 0, 1, -1, 0 };
    int n = arr.Length;
    Console.WriteLine(findmax_zeroprefixes(arr, n));
  }
}
  
// This code is contributed by lokesh.


Javascript




// JavaScript code for the above approach
  
// Function to find maximum 0 prefix sums
// after replacing 0's
function findmax_zeroprefixes(arr, n) 
{
  
    // Initialize the arrays say prefix_sum
    // to store the prefix sum and the array
    // end mark to the mark array to mark
    // the end of subarray starting with 0.
    let prefix_sum = new Array(n).fill(0);
  
    let endmark = new Array(n).fill(0);
  
    // Initialize the variables flag to
    // check whether 0 as occurred before
    // and max_freq to store the maximum
    // frequency of prefix sums of each
    // subarray and res to store max
    // possible 0 prefix sums.
    let flag = 0;
    let max_freq = 0;
    let res = 0;
  
    if (arr[0] == 0) {
        flag = 1;
    }
  
    // Traverse through the array and mark
    // the end of subarray starting with 0.
    for (let i = 0; i < n; i++) {
  
        if (i + 1 < n) {
            if (arr[i + 1] == 0) {
                endmark[i] = true;
            }
            else {
                endmark[i] = false;
            }
        }
        else {
            endmark[i] = true;
        }
    }
  
    // Build the prefix sum array
    // of the array arr[]
    prefix_sum[0] = arr[0];
  
    for (let i = 1; i < n; i++) {
        prefix_sum[i] = prefix_sum[i - 1] + arr[i];
    }
  
    res = 0;
  
    // Initialize a map  to store
    // the frequencies
    let freq = new Map();
    max_freq = 0;
  
    // Iterate through the array and add
    // the frequency of most frequent
    // prefix sum  of each subarray
    // starting with 0 to the res.
    for (let i = 0; i < n; i++) {
  
        // If endmark of that index is false
        // keep the frequency of prefix sum
        // at that index increasing
        if (endmark[i] == false) {
  
            if (freq.has(prefix_sum[i])) {
                freq.set(prefix_sum[i], freq.get(prefix_sum[i]) + 1);
            }
            else {
                freq.set(prefix_sum[i], 1);
            }
            max_freq = Math.max(max_freq, freq.get(prefix_sum[i]));
        }
  
        // Else add the maximum frequent
        // prefix sum to the res.
        else {
  
            if (freq.has(prefix_sum[i])) {
                freq.set(prefix_sum[i], freq.get(prefix_sum[i]) + 1);
            }
            else {
                freq.set(prefix_sum[i], 1);
            }
            if(freq.has(prefix_sum[i]))
            max_freq = Math.max(max_freq, freq.get(prefix_sum[i]));
  
            // For the first subarray whose
            // sum is 0
            if (flag == 0) {
  
                // Add the frequency of
                // zero prefixsums
                if(freq.has(0))
                res = res + freq.get(0);
                max_freq = 0;
                freq.clear();
                flag = 1;
            }
              
            // For the remaining subarrays starting
            // with 0's
            else {
  
                // Add the max frequency
                res = res + max_freq;
                freq.clear();
                max_freq = 0;
            }
        }
    }
      
    // Return the res
    return res;
}
  
// Driver function
let arr = [2, 0, 1, -1, 0];
let n = arr.length;
console.log(findmax_zeroprefixes(arr, n));
  
// This code is contributed by poojaagarwal2.


Output

3

Time Complexity: O(N) 
Auxiliary Space: O(N)

Related Articles:

  • Introduction to Arrays – Data Structure and Algorithm Tutorials


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads