Minimize count of flips required to make sum of the given array equal to 0
Last Updated :
09 Nov, 2023
Given an array arr[] consisting of N integers, the task is to minimize the count of elements required to be multiplied by -1 such that the sum of array elements is 0. If it is not possible to make the sum 0, print "-1".
Examples:
Input: arr[] = {2, 3, 1, 4}
Output: 2
Explanation:
Multiply arr[0] by -1. Therefore, the array modifies to {-2, 3, 1, 4}.
Multiply arr[1] by -1. Therefore, the array modifies to {-2, -3, 1, 4}
Therefore, the sum of the modified array is 0 and the minimum operations required is 2.
Input: arr[] = {2}
Output: -1
Naive Approach: The simplest approach is to divide the array into two subsets in every possible way. For each division, check if the difference of their subset-sum is 0 or not. If found to be 0, then the length of the smaller subset is the result.
Time Complexity: O(2N)
Auxiliary Space: O(N)
Efficient Approach: To optimize the above approach, the idea is to use Dynamic Programming. Follow the steps to solve the problem:
- To make the sum of all array elements equal to 0, divide the given array elements into two subsets having an equal sum.
- Out of all the subsets possible of the given array, the subset whose size is the minimum of all is chosen.
- If the sum of the given array is odd, no subset is possible to make the sum 0, hence return -1
- Else, try all possible subset sums of the array and check if the sum of the subset is equal to sum/2. where the sum is the sum of all elements of the array.
- The recurrence relation of dp[] is:
dp(i, j) = min (dp(i+1, j - arr[i]]+1), dp(i+1, j))
where
dp (i, j) represents the minimum operations to make sum j equal to 0 using elements having index [i, N-1].
j represents the current sum.
i represents the current index.
- Using the above recurrence, print dp(0, sum/2) as the result.
Below is the implementation of the above approach:
C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Initialize dp[][]
int dp[2001][2001];
// Function to find the minimum number
// of operations to make sum of A[] 0
int solve(vector<int>& A, int i,
int sum, int N)
{
// Initialize answer
int res = 2001;
// Base case
if (sum < 0 or (i == N and sum != 0)) {
return 2001;
}
// Otherwise, return 0
if (sum == 0 or i >= N) {
return dp[i][sum] = 0;
}
// Pre-computed subproblem
if (dp[i][sum] != -1) {
return dp[i][sum];
}
// Recurrence relation for finding
// the minimum of the sum of subsets
res = min(solve(A, i + 1, sum - A[i], N) + 1,
solve(A, i + 1, sum, N));
// Return the result
return dp[i][sum] = res;
}
// Function to find the minimum number
// of elements required to be flipped
// to make sum the array equal to 0
void minOp(vector<int>& A, int N)
{
int sum = 0;
// Find the sum of array
for (auto it : A) {
sum += it;
}
if (sum % 2 == 0) {
// Initialise dp[][] with -1
memset(dp, -1, sizeof(dp));
int ans = solve(A, 0, sum / 2, N);
// No solution exists
if (ans < 0 || ans > N) {
cout << "-1" << endl;
}
// Otherwise
else {
cout << ans << endl;
}
}
// If sum is odd, no
// subset is possible
else {
cout << "-1" << endl;
}
}
// Driver Code
int main()
{
vector<int> A = { 2, 3, 1, 4 };
int N = A.size();
// Function Call
minOp(A, N);
return 0;
}
Java
// Java program for the above approach
class GFG
{
// Initialize dp[][]
static int [][]dp = new int[2001][2001];
// Function to find the minimum number
// of operations to make sum of A[] 0
static int solve(int []A, int i,
int sum, int N)
{
// Initialize answer
int res = 2001;
// Base case
if (sum < 0 || (i == N && sum != 0))
{
return 2001;
}
// Otherwise, return 0
if (sum == 0 || i >= N)
{
return dp[i][sum] = 0;
}
// Pre-computed subproblem
if (dp[i][sum] != -1)
{
return dp[i][sum];
}
// Recurrence relation for finding
// the minimum of the sum of subsets
res = Math.min(solve(A, i + 1, sum - A[i], N) + 1,
solve(A, i + 1, sum, N));
// Return the result
return dp[i][sum] = res;
}
// Function to find the minimum number
// of elements required to be flipped
// to make sum the array equal to 0
static void minOp(int []A, int N)
{
int sum = 0;
// Find the sum of array
for (int it : A)
{
sum += it;
}
if (sum % 2 == 0)
{
// Initialise dp[][] with -1
for(int i = 0; i < 2001; i++)
{
for (int j = 0; j < 2001; j++)
{
dp[i][j] = -1;
}
}
int ans = solve(A, 0, sum / 2, N);
// No solution exists
if (ans < 0 || ans > N)
{
System.out.print("-1" +"\n");
}
// Otherwise
else
{
System.out.print(ans +"\n");
}
}
// If sum is odd, no
// subset is possible
else
{
System.out.print("-1" +"\n");
}
}
// Driver Code
public static void main(String[] args)
{
int []A = { 2, 3, 1, 4 };
int N = A.length;
// Function Call
minOp(A, N);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python program for the above approach
# Initialize dp[][]
dp = [[-1 for i in range(2001)] for j in range(2001)]
# Function to find the minimum number
# of operations to make sum of A[] 0
def solve(A, i, sum, N):
# Initialize answer
res = 2001
# Base case
if (sum < 0 or (i == N and sum != 0)):
return 2001
# Otherwise, return 0
if (sum == 0 or i >= N):
dp[i][sum] = 0
return 0
# Pre-computed subproblem
if (dp[i][sum] != -1):
return dp[i][sum]
# Recurrence relation for finding
# the minimum of the sum of subsets
res = min(solve(A, i + 1, sum - A[i], N) + 1,
solve(A, i + 1, sum, N))
# Return the result
dp[i][sum] = res
return res
# Function to find the minimum number
# of elements required to be flipped
# to make sum the array equal to 0
def minOp(A, N):
sum = 0
# Find the sum of array
for it in A:
sum += it
if (sum % 2 == 0):
# Initialise dp[][] with -1
dp = [[-1 for i in range(2001)] for j in range(2001)]
ans = solve(A, 0, sum // 2, N)
# No solution exists
if (ans < 0 or ans > N):
print("-1")
# Otherwise
else:
print(ans)
# If sum is odd, no
# subset is possible
else:
print(-1)
# Driver Code
A = [ 2, 3, 1, 4 ]
N = len(A)
# Function Call
minOp(A, N)
# This code is contributed by rohitsingh07052.
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
public class GFG
{
// Initialize [,]dp
static int [,]dp = new int[2001,2001];
// Function to find the minimum number
// of operations to make sum of []A 0
static int solve(int []A, int i,
int sum, int N)
{
// Initialize answer
int res = 2001;
// Base case
if (sum < 0 || (i == N && sum != 0))
{
return 2001;
}
// Otherwise, return 0
if (sum == 0 || i >= N)
{
return dp[i, sum] = 0;
}
// Pre-computed subproblem
if (dp[i, sum] != -1)
{
return dp[i, sum];
}
// Recurrence relation for finding
// the minimum of the sum of subsets
res = Math.Min(solve(A, i + 1, sum - A[i], N) + 1,
solve(A, i + 1, sum, N));
// Return the result
return dp[i, sum] = res;
}
// Function to find the minimum number
// of elements required to be flipped
// to make sum the array equal to 0
static void minOp(int []A, int N)
{
int sum = 0;
// Find the sum of array
foreach (int it in A)
{
sum += it;
}
if (sum % 2 == 0)
{
// Initialise [,]dp with -1
for(int i = 0; i < 2001; i++)
{
for (int j = 0; j < 2001; j++)
{
dp[i, j] = -1;
}
}
int ans = solve(A, 0, sum / 2, N);
// No solution exists
if (ans < 0 || ans > N)
{
Console.Write("-1" +"\n");
}
// Otherwise
else
{
Console.Write(ans +"\n");
}
}
// If sum is odd, no
// subset is possible
else
{
Console.Write("-1" +"\n");
}
}
// Driver Code
public static void Main(String[] args)
{
int []A = { 2, 3, 1, 4 };
int N = A.Length;
// Function Call
minOp(A, N);
}
}
// This code is contributed by 29AjayKumar
JavaScript
<script>
// JavaScript program for the above approach
// Initialize dp[][]
let dp= [];
for(var i=0; i<2001; i++) {
dp[i] = [];
for(var j=0; j<2001; j++) {
dp[i][j] = -1;
}
}
// Function to find the minimum number
// of operations to make sum of A[] 0
function solve( A, i, sum, N){
// Initialize answer
let res = 2001;
// Base case
if (sum < 0 || (i == N && sum != 0)) {
return 2001;
}
// Otherwise, return 0
if (sum == 0 || i >= N) {
dp[i][sum] = 0;
return dp[i][sum];
}
// Pre-computed subproblem
if (dp[i][sum] != -1) {
return dp[i][sum];
}
// Recurrence relation for finding
// the minimum of the sum of subsets
res = Math.min(solve(A, i + 1, sum - A[i], N) + 1,
solve(A, i + 1, sum, N));
// Return the result
dp[i][sum] = res;
return dp[i][sum];
}
// Function to find the minimum number
// of elements required to be flipped
// to make sum the array equal to 0
function minOp(A, N){
let sum = 0;
// Find the sum of array
for (let i =0; i< A.length; i++) {
sum += A[i];
}
if (sum % 2 == 0) {
let dp= [];
for(var i=0; i<2001; i++) {
dp[i] = [];
for(var j=0; j<2001; j++) {
dp[i][j] = -1;
}
}
let ans = solve(A, 0, Math.floor(sum / 2), N);
// No solution exists
if (ans < 0 || ans > N) {
document.write("-1 <br>");
}
// Otherwise
else {
document.write(ans,"<br>");
}
}
// If sum is odd, no
// subset is possible
else {
document.write("-1 <br>");
}
}
// Driver Code
let A = [ 2, 3, 1, 4 ];
let N = A.length;
// Function Call
minOp(A, N);
</script>
Time Complexity: O(S*N), where S is the sum of the given array.
Auxiliary Space: O(S*N)
Efficient approach : Using DP Tabulation method ( Iterative approach )
The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.
Implementation :
C++
#include <bits/stdc++.h>
using namespace std;
// create DP to store previous computations
int dp[2001][2001];
// Function to find the minimum number
// of operations to make sum of A[] 0
void minOp(vector<int>& A, int N)
{
int sum = 0;
// Find the sum of array
for (auto it : A) {
sum += it;
}
if (sum % 2 == 0) {
int target = sum / 2;
// Initialize dp table
for (int i = 0; i <= N; i++) {
dp[i][0] = 0;
}
for (int j = 1; j <= target; j++) {
dp[N][j] = 2001;
}
// Fill dp table in bottom-up manner
for (int i = N - 1; i >= 0; i--) {
for (int j = 1; j <= target; j++) {
if (j >= A[i]) {
dp[i][j] = min(dp[i + 1][j],
dp[i + 1][j - A[i]] + 1);
}
else {
dp[i][j] = dp[i + 1][j];
}
}
}
// No solution exists
if (dp[0][target] >= 2001) {
cout << "-1" << endl;
}
// Otherwise
else {
cout << dp[0][target] << endl;
}
}
// If sum is odd, no subset is possible
else {
cout << "-1" << endl;
}
}
int main()
{
vector<int> A = { 2, 3, 1, 4 };
int N = A.size();
// Function Call
minOp(A, N);
return 0;
}
Java
import java.util.Arrays;
import java.util.List;
public class Main {
// create DP to store previous computations
static int[][] dp;
// Function to find the minimum number of operations to
// make sum of A[] 0
static void minOp(List<Integer> A, int N)
{
int sum = 0;
// Find the sum of the array
for (int it : A) {
sum += it;
}
if (sum % 2 == 0) {
int target = sum / 2;
// Initialize dp table
dp = new int[N + 1][target + 1];
for (int i = 0; i <= N; i++) {
Arrays.fill(dp[i], 0);
}
for (int j = 1; j <= target; j++) {
dp[N][j] = 2001;
}
// Fill dp table in bottom-up manner
for (int i = N - 1; i >= 0; i--) {
for (int j = 1; j <= target; j++) {
if (j >= A.get(i)) {
dp[i][j] = Math.min(
dp[i + 1][j],
dp[i + 1][j - A.get(i)] + 1);
}
else {
dp[i][j] = dp[i + 1][j];
}
}
}
// No solution exists
if (dp[0][target] >= 2001) {
System.out.println("-1");
}
// Otherwise
else {
System.out.println(dp[0][target]);
}
}
else {
// If the sum is odd, no subset is possible
System.out.println("-1");
}
}
public static void main(String[] args)
{
List<Integer> A = Arrays.asList(2, 3, 1, 4);
int N = A.size();
// Function Call
minOp(A, N);
}
}
Python
def min_op(A):
sum = 0
# Find the sum of array
for num in A:
sum += num
if sum % 2 == 0:
target = sum // 2
N = len(A)
# Initialize dp table
dp = [[0 for _ in range(target + 1)] for _ in range(N + 1)]
# Fill dp table in bottom-up manner
for i in range(N - 1, -1, -1):
for j in range(target, -1, -1):
if j >= A[i]:
dp[i][j] = max(dp[i + 1][j], dp[i + 1][j - A[i]] + 1)
else:
dp[i][j] = dp[i + 1][j]
# No solution exists
if dp[0][target] == 0:
print("-1")
# Otherwise
else:
print(dp[0][target])
# If sum is odd, no subset is possible
else:
print("-1")
if __name__ == "__main__":
A = [2, 3, 1, 4]
min_op(A)
C#
using System;
class GFG {
// Function to find the minimum number
// of operations to make sum of A[] 0
static void MinOp(int[] A, int N)
{
int sum = 0;
// Find the sum of array
foreach(var num in A) { sum += num; }
if (sum % 2 == 0) {
int target = sum / 2;
// Initialize dp table
int[, ] dp = new int[N + 1, target + 1];
for (int i = 0; i <= N; i++) {
dp[i, 0] = 0;
}
for (int j = 1; j <= target; j++) {
dp[N, j] = 2001;
}
// Fill dp table in bottom-up manner
for (int i = N - 1; i >= 0; i--) {
for (int j = 1; j <= target; j++) {
if (j >= A[i]) {
dp[i, j] = Math.Min(
dp[i + 1, j],
dp[i + 1, j - A[i]] + 1);
}
else {
dp[i, j] = dp[i + 1, j];
}
}
}
// No solution exists
if (dp[0, target] >= 2001) {
Console.WriteLine("-1");
}
// Otherwise
else {
Console.WriteLine(dp[0, target]);
}
}
// If sum is odd, no subset is possible
else {
Console.WriteLine("-1");
}
}
static void Main()
{
int[] A = { 2, 3, 1, 4 };
int N = A.Length;
// Function Call
MinOp(A, N);
}
}
JavaScript
// Function to find the minimum number
// of operations to make sum of A[] 0
function minOp(A) {
const N = A.length;
let sum = 0;
// Find the sum of array
for (let i = 0; i < N; i++) {
sum += A[i];
}
if (sum % 2 === 0) {
const target = sum / 2;
// Initialize dp table
const dp = new Array(N + 1).fill(null).map(() => new Array(target + 1).fill(0));
for (let j = 1; j <= target; j++) {
dp[N][j] = 2001;
}
// Fill dp table in bottom-up manner
for (let i = N - 1; i >= 0; i--) {
for (let j = 1; j <= target; j++) {
if (j >= A[i]) {
dp[i][j] = Math.min(dp[i + 1][j],
dp[i + 1][j - A[i]] + 1);
} else {
dp[i][j] = dp[i + 1][j];
}
}
}
// No solution exists
if (dp[0][target] >= 2001) {
console.log("-1");
}
// Otherwise
else {
console.log(dp[0][target]);
}
} else {
// If sum is odd, no subset is possible
console.log("-1");
}
}
const A = [2, 3, 1, 4];
minOp(A);
Time Complexity: O(S*N), where S is the sum of the given array.
Auxiliary Space: O(S*N)
Efficient approach : Space optimization
In previous approach the current value dp[i][j] is only depend upon the current and previous row values of DP. So to optimize the space complexity we use a single 1D array to store the computations.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
// Function to find the minimum number
// of operations to make sum of A[] 0
int minOp(vector<int>& A, int N)
{
int sum = 0;
// Find the sum of array
for (auto it : A) {
sum += it;
}
if (sum % 2 == 0) {
int target = sum / 2;
// Initialize dp table
vector<int> dp(target + 1, 2001);
dp[0] = 0;
// Fill dp table in bottom-up manner
for (int i = 0; i < N; i++) {
for (int j = target; j >= A[i]; j--) {
dp[j] = min(dp[j], dp[j - A[i]] + 1);
}
}
// No solution exists
if (dp[target] >= 2001) {
cout << "-1" << endl;
}
// Otherwise
else {
cout << dp[target] << endl;
}
}
// If sum is odd, no subset is possible
else {
cout << "-1" << endl;
}
}
int main()
{
vector<int> A = { 2, 3, 1, 4 };
int N = A.size();
// Function Call
minOp(A, N);
return 0;
}
Java
import java.util.Arrays;
public class Main {
// Function to find the minimum number of operations to
// make the sum of A[] 0
static int minOp(int[] A, int N)
{
int sum = 0;
// Find the sum of the array
for (int value : A) {
sum += value;
}
if (sum % 2 == 0) {
int target = sum / 2;
// Initialize dp table
int[] dp = new int[target + 1];
Arrays.fill(dp, 2001);
dp[0] = 0;
// Fill dp table in a bottom-up manner
for (int i = 0; i < N; i++) {
for (int j = target; j >= A[i]; j--) {
dp[j]
= Math.min(dp[j], dp[j - A[i]] + 1);
}
}
// No solution exists
if (dp[target] >= 2001) {
System.out.println("-1");
}
// Otherwise
else {
System.out.println(dp[target]);
}
}
// If the sum is odd, no subset is possible
else {
System.out.println("-1");
}
return 0;
}
public static void main(String[] args)
{
int[] A = { 2, 3, 1, 4 };
int N = A.length;
// Function Call
minOp(A, N);
}
}
Python
def min_op(A):
N = len(A)
sum_of_elements = sum(A)
# Check if the sum of the elements is even
if sum_of_elements % 2 == 0:
target = sum_of_elements // 2
# Initialize a list to store the minimum operations required for each sum
dp = [float('inf')] * (target + 1)
dp[0] = 0
# Fill the dp list in a bottom-up manner
for i in range(N):
for j in range(target, A[i] - 1, -1):
dp[j] = min(dp[j], dp[j - A[i]] + 1)
# No solution exists
if dp[target] == float('inf'):
print("-1")
else:
print(dp[target])
else:
# If the sum is odd, no subset is possible
print("-1")
if __name__ == "__main__":
A = [2, 3, 1, 4]
# Function Call
min_op(A)
C#
using System;
class Program {
// Function to find the minimum number of operations to
// make the sum of A[] 0
static void MinOp(int[] A, int N)
{
int sum = 0;
// Find the sum of the array
foreach(int num in A) { sum += num; }
if (sum % 2 == 0) {
int target = sum / 2;
// Initialize dp table
int[] dp = new int[target + 1];
for (int i = 0; i <= target; i++) {
dp[i] = 2001;
}
dp[0] = 0;
// Fill dp table in bottom-up manner
for (int i = 0; i < N; i++) {
for (int j = target; j >= A[i]; j--) {
dp[j]
= Math.Min(dp[j], dp[j - A[i]] + 1);
}
}
// No solution exists
if (dp[target] >= 2001) {
Console.WriteLine("-1");
}
else {
// Otherwise, print the minimum number of
// operations
Console.WriteLine(dp[target]);
}
}
else {
// If sum is odd, no subset is possible
Console.WriteLine("-1");
}
}
static void Main()
{
int[] A = { 2, 3, 1, 4 };
int N = A.Length;
// Function Call
MinOp(A, N);
}
}
JavaScript
// Function to find the minimum number of operations to
// make the sum of A[] 0
function minOp(A, N) {
let sum = 0;
// Find the sum of the array
for (let i = 0; i < N; i++) {
sum += A[i];
}
if (sum % 2 === 0) {
let target = sum / 2;
// Initialize dp table
let dp = new Array(target + 1);
for (let i = 0; i <= target; i++) {
dp[i] = 2001;
}
dp[0] = 0;
// Fill dp table in a bottom-up manner
for (let i = 0; i < N; i++) {
for (let j = target; j >= A[i]; j--) {
dp[j] = Math.min(dp[j], dp[j - A[i]] + 1);
}
}
// No solution exists
if (dp[target] >= 2001) {
console.log("-1");
} else {
// Otherwise, print the minimum number of operations
console.log(dp[target]);
}
} else {
// If the sum is odd, no subset is possible
console.log("-1");
}
}
// Test case
const A = [2, 3, 1, 4];
const N = A.length;
// Function Call
minOp(A, N);
Time Complexity: O(S*N), where S is the sum of the given array.
Auxiliary Space: O(target), where target is S/2
Similar Reads
Minimize flips on K-length subarrays required to make all array elements equal to 1
Given a binary array arr[] of size N and a positive integer K, the task is to find the minimum number of times any subarray of size K from the given array arr[] is required to be flipped to make all array elements equal to 1. If it is not possible to do so, then print "-1". Examples: Input: arr[] =
15+ min read
Minimize cost required to make all array elements greater than or equal to zero
Given an array arr[] consisting of N integers and an integer X, the task is to find the minimum cost required to make all array elements greater than or equal to 0 by performing the following operations any number of times: Increase any array element by 1. Cost = 1.Increase all array elements by 1.
7 min read
Minimize operations required to make each element of Array equal to it's index value
Given an array arr[] consisting of N integers, the task is to modify the array such that arr[index] = index using minimum number of operations of the following type: Choose any index i and any integer X, and add X to all the elements in the range [0, i].Choose any index i and any integer X, and chan
7 min read
Min cost required to make the Array sum zero consisting of 1 and -1
Given an array arr[] of size N containing only +1 and -1, the task is to make the sum of the array zero with the given operation. In a single operation, any element can be updated as arr[i] = arr[i] * (-1). Each operation cost 10 units. the task is to print the minimum cost required to make the sum
6 min read
Minimize Bitwise XOR of array elements with 1 required to make sum of array at least K
Given an array arr[] consisting of N positive integers and a positive integer K, the task is to count minimum Bitwise XOR of array elements with 1 required such that the sum of the array is at least K. Examples: Input: arr[] = {0, 1, 1, 0, 1}, K = 4Output: 1Explanation: Performing Bitwise XOR of arr
6 min read
Minimum swaps of same-indexed elements required to make sum of two given arrays even
Given two arrays arr1[] and arr2[] of size N, the task is to count the minimum number of swaps of same-indexed elements from both the arrays arr1[] and arr2[] required to make the sum of all elements of both the arrays even. If it is not possible, then print "-1". Examples: Input: arr1[] = {1, 4, 2,
9 min read
Minimize increments or decrements required to make sum and product of array elements non-zero
Given an array arr[] of N integers, the task is to count the minimum number of increment or decrement operations required on the array such that the sum and product of all the elements of the array arr[] are non-zero. Examples: Input: arr[] = {-1, -1, 0, 0}Output: 2Explanation: Perform the following
6 min read
Minimum swaps of similar indexed elements required to make all elements of one of the two given arrays equal
Given two arrays A[] and B[] of size N, the task is to count the minimum number of swaps of similar indexed elements required to make one of the two given arrays equal. If it is not possible to make all elements of an array equal, then print -1. Examples: Input: A[] = {3, 4, 1, 3, 1, 3, 4}, B[] = {1
12 min read
Minimize Cost to reduce the Array to a single element by given operations
Given an array a[] consisting of N integers and an integer K, the task is to find the minimum cost to reduce the given array to a single element by choosing any pair of consecutive array elements and replace them by (a[i] + a[i+1]) for a cost K * (a[i] + a[i+1]). Examples: Input: a[] = {1, 2, 3}, K
15+ min read
Minimize cost of insertions and deletions required to make all array elements equal
Given a sorted array arr[] of size N (1 ? N ? 105) and two integers A and B, the task is to calculate the minimum cost required to make all array elements equal by increments or decrements. The cost of each increment and decrement are A and B respectively. Examples: Input: arr[] = { 2, 5, 6, 9, 10,
11 min read