Find partitions that maximises sum of count of 0’s in left part and count of 1’s in right part in C++


Programming requires regular optimization of algorithms geared toward specific outcomes. One fundamental task is identifying partitions of arrays within C++ that maximize sums made up entirely of left-side zeros and right-side ones. To achieve a solution, this article will survey different approaches alongside step-by-step instructions and two functional code demonstrations.

Syntax

To make sure our readers have an easy time following along with our code examples. It's critical that we establish a consistent syntax upfront. So before getting into algorithms and approaches let's determine this essential baseline. −

#include <iostream>
#include <vector>
using namespace std;

// Function to find partitions with maximum zero and one counts
pair<int, int> findMaxPartition(const vector<int>& arr) {
   // Implementation code
}

Algorithm

Here is a step-by-step breakdown of our algorithm −

  • Initialize two counters, zeroCount and oneCount, to 0.

  • Initialize two variables, maxZeroCount and maxOneCount, to 0.

  • Iterate through the array arr from left to right −

  • Increment zeroCount if the element is 0.

  • Increment oneCount if the element is 1.

  • Iterate through the array arr from left to right again −

  • Decrement zeroCount if the element is 0.

  • Decrement oneCount if the element is 1.

  • Update maxZeroCount to the maximum value between maxZeroCount and zeroCount.

  • Update maxOneCount to the maximum value between maxOneCount and oneCount.

  • Return a pair containing maxZeroCount and maxOneCount.

Approach 1: Greedy Approach

The greedy approach focuses on finding the maximum count of zeros in the left part and ones in the right part by iterating through the array only once. It follows the algorithm described earlier.

Example

#include <iostream>
#include <vector>
using namespace std;

pair<int, int> findMaxPartition(const vector<int>& arr) {
   int zeroCount = 0, oneCount = 0;
   int maxZeroCount = 0, maxOneCount = 0;

   for (int i = 0; i < arr.size(); i++) {
      zeroCount += (arr[i] == 0);
      oneCount += (arr[i] == 1);
   }

   for (int i = 0; i < arr.size(); i++) {
      zeroCount -= (arr[i] == 0);
      oneCount -= (arr[i] == 1);
      maxZeroCount = max(maxZeroCount, zeroCount);
      maxOneCount = max(maxOneCount, oneCount);
   }

   return make_pair(maxZeroCount, maxOneCount);
}

int main() {
   // Test the findMaxPartition function
   vector<int> arr = {0, 1, 0, 1, 1, 0, 0};
   pair<int, int> result = findMaxPartition(arr);

   cout << "Max Zero Count: " << result.first << endl;
   cout << "Max One Count: " << result.second << endl;

   return 0;
}

Output

Max Zero Count: 3
Max One Count: 3

Explanation

First, the necessary libraries are included − <iostream> for input/output operations and <vector> for using dynamic arrays.

The using namespace std; statement allows us to use the standard library functions and objects without explicitly specifying the std:: prefix, which enhances code readability.

Next, the function findMaxPartition is defined. It takes a constant reference to a vector of integers, denoted as const vector<int>& arr, representing the input array. The pair of integers that this function returns indicate the maximum count of zeros and ones respectively.

The declaration within this function involves four variables - zeroCount as well as oneCount are used to maintain updates on current count for zeros or ones respectively, while storing record of highest counts thus far falls under maxZeroCounts or maxOneCounts.

The input array arr undergoes an initial loop where each element's value (0 or 1) determines the zeroCount and oneCount variables to be incremented.

The second loop iterates over the array again, but this time it decrements the zeroCount and oneCount variables while updating the maxZeroCount and maxOneCount variables with the maximum values encountered so far.

After the loops, the function returns a pair created using make_pair containing the maximum counts of zeros and ones.

The arr vector in the main function is initialized with values {0, 1. 0. 1. 1. 0. 0} to set up a test case. Following this step the findMaxPartition function is called to process this array. The outcome of this operation is then stored in the result variable as a pair of maximum counts.

Finally, the maximum counts of zeros and ones are printed to the console using cout, ensuring a clear display of the desired outputs.

Overall, this code effectively finds and displays the maximum counts of zeros and ones in the given array, showcasing the functionality of the approach to partition optimization.

Approach 2: Dynamic Programming Approach

The dynamic programming approach uses memoization to store the counts of zeros and ones at each index of the array. By utilizing the previously computed values, we can find the maximum counts.

Example

#include <iostream>
#include <vector>
using namespace std;

pair<int, int> findMaxPartition(const vector<int>& arr) {
   int n = arr.size();
   vector<int> zeroCount(n + 1, 0);
   vector<int> oneCount(n + 1, 0);

   for (int i = 1; i <= n; i++) {
      zeroCount[i] = zeroCount[i - 1] + (arr[i - 1] == 0);
      oneCount[i] = oneCount[i - 1] + (arr[i - 1] == 1);
   }
   int maxZeroCount = 0, maxOneCount = 0;

   for (int i = 0; i < n; i++) {
      int zerosLeft = zeroCount[i];
      int onesRight = oneCount[n] - oneCount[i];
      maxZeroCount = max(maxZeroCount, zerosLeft + onesRight);
      maxOneCount = max(maxOneCount, zeroCount[n] - zerosLeft + oneCount[i]);
   }
   return make_pair(maxZeroCount, maxOneCount);
}

int main() {
   // Test the findMaxPartition function
   vector<int> arr = {0, 1, 0, 1, 1, 0, 0};
   pair<int, int> result = findMaxPartition(arr);

   cout << "Max Zero Count: " << result.first << endl;
   cout << "Max One Count: " << result.second << endl;

   return 0;
}

Output

Max Zero Count: 4
Max One Count: 5

Explanation

The findMaxPartition function takes a constant reference to a vector of integers arr and returns a pair of integers representing the maximum count of zeros and ones, respectively.

Dynamic programming is employed within our function to facilitate counting and record keeping for cumulative zeros and ones at each index in an input array. To accomplish this we initialized two vectors- zeroCount and oneCount- when executing our function. By analyzing values in the input array we are able to calculate these counts for every index.

Moving on, the function begins to iterate through each element in the array with a specific aim- to obtain an accurate count of maximum zeros and ones across a range of partitions. To achieve this, it calculates both “zerosLeft” and “onesRight" for every probable partition.The maximum counts are updated accordingly.

The main function begins by initializing the arr vector with specific values {0 ,1 ,0 ,1 ,1 ,0 ,0}, which serves to establish a particular test case. Subsequently,the findMaxPartition function gets triggered with our recently crafted array as its input parameter.As a product of successfully running this algorithm program,the resultant maximum counts are stored neatly within an easily accessible result variable.

Finally, the maximum counts of zeros and ones are printed to the console using cout, providing the desired output.

This code effectively applies the dynamic programming approach to solve the partitioning problem and produces the expected results..

Conclusion

In this article, we explored two approaches to find partitions that maximize the sum of zero counts in the left part and one counts in the right part of an array in C++. The greedy approach performs the task efficiently by iterating through the array only once, while the dynamic programming approach utilizes memoization for efficient computation.Optimizing algorithms for comparable partitioning duties in C++ necessitates a comprehensive comprehension of both approaches and selecting which one suits best depending on individual circumstances. Programmers who apply this knowledge meticulously will be able to achieve their vision with ease.

Updated on: 25-Jul-2023

25 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements