Subset with sum closest to zero

Given an array ‘arr’ consisting of integers, the task is to find the non-empty subset such that its sum is closest to zero i.e. absolute difference between zero and the sum is minimum.
Examples:
Input : arr[] = {2, 2, 2, -4}
Output : 0
arr[0] + arr[1] + arr[3] = 0
That’s why answer is zero.
Input : arr[] = {1, 1, 1, 1}
Output : 1
One simple approach is to generate all possible subsets recursively and find the one with the sum closest to zero. Time complexity of this approach will be O(2^n).
A better approach will be using Dynamic programming in Pseudo Polynomial Time Complexity .
Let’s suppose sum of all the elements we have selected upto index ‘i-1’ is ‘S’. So, starting from index ‘i’, we have to find a subset with sum closest to -S.
Let’s define dp[i][S] first. It means sum of the subset of the subarray{i, N-1} of array ‘arr’ with sum closest to ‘-S’.
Now, we can include ‘i’ in the current sum or leave it. Thus we, have two possible paths to take. If we include ‘i’, current sum will be updated as S+arr[i] and we will solve for index ‘i+1’ i.e. dp[i+1][S+arr[i]] else we will solve for index ‘i+1’ directly. Thus, the required recurrence relation will be.
dp[i][s] = RetClose(arr[i]+dp[i][s+arr[i]], dp[i+1][s], -s);
where RetClose(a, b, c) returns a if |a-c|<|b-c| else it returns b
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>using namespace std;#define arrSize 51#define maxSum 201#define MAX 100#define inf 999999 // Variable to store states of dpint dp[arrSize][maxSum];bool visit[arrSize][maxSum]; // Function to return the number closer to integer sint RetClose(int a, int b, int s){ if (abs(a - s) < abs(b - s)) return a; else return b;} // To find the sum closest to zero// Since sum can be negative, we will add MAX// to it to make it positiveint MinDiff(int i, int sum, int arr[], int n){ // Base cases if (i == n) return 0; // Checks if a state is already solved if (visit[i][sum + MAX]) return dp[i][sum + MAX]; visit[i][sum + MAX] = 1; // Recurrence relation dp[i][sum + MAX] = RetClose(arr[i] + MinDiff(i + 1, sum + arr[i], arr, n), MinDiff(i + 1, sum, arr, n), -1 * sum); // Returning the value return dp[i][sum + MAX];}// Function to calculate the closest sum valuevoid FindClose(int arr[],int n){ int ans=inf; // Calculate the Closest value for every // subarray arr[i-1:n] for (int i = 1; i <= n; i++) ans = RetClose(arr[i - 1] + MinDiff(i, arr[i - 1], arr, n), ans, 0); cout<<ans<<endl;} // Driver functionint main(){ // Input array int arr[] = { 25, -9, -10, -4, -7, -33 }; int n = sizeof(arr) / sizeof(int); FindClose(arr,n); return 0;} |
Java
// Java Program for above approachimport java.io.*;class GFG { static int arrSize = 51;static int maxSum = 201;static int MAX = 100;static int inf = 999999;// Variable to store states of dpstatic int dp[][] = new int [arrSize][maxSum];static int visit[][] = new int [arrSize][maxSum];// Function to return the number // closer to integer sstatic int RetClose(int a, int b, int s){ if (Math.abs(a - s) < Math.abs(b - s)) return a; else return b;}// To find the sum closest to zero// Since sum can be negative, we will add MAX// to it to make it positivestatic int MinDiff(int i, int sum, int arr[], int n){ // Base cases if (i == n) return 0; // Checks if a state is already solved if (visit[i][sum + MAX] > 0 ) return dp[i][sum + MAX]; visit[i][sum + MAX] = 1; // Recurrence relation dp[i][sum + MAX] = RetClose(arr[i] + MinDiff(i + 1, sum + arr[i], arr, n), MinDiff(i + 1, sum, arr, n), -1 * sum); // Returning the value return dp[i][sum + MAX];}// Function to calculate the closest sum valuestatic void FindClose(int arr[], int n){ int ans = inf; // Calculate the Closest value for every // subarray arr[i-1:n] for (int i = 1; i <= n; i++) ans = RetClose(arr[i - 1] + MinDiff(i, arr[i - 1], arr, n), ans, 0); System.out.println(ans);}// Driver Codepublic static void main (String[] args) { // Input array int arr[] = { 25, -9, -10, -4, -7, -33 }; int n = arr.length; FindClose(arr,n);}}// This code is contributed by ajit_00023@ |
Python3
# Python3 Code for above implementationimport numpy as nparrSize = 51maxSum = 201MAX = 100inf = 999999# Variable to store states of dp dp = np.zeros((arrSize,maxSum)); visit = np.zeros((arrSize,maxSum)); # Function to return the number closer to integer s def RetClose(a, b, s) : if (abs(a - s) < abs(b - s)) : return a; else : return b; # To find the sum closest to zero # Since sum can be negative, we will add MAX # to it to make it positive def MinDiff(i, sum, arr, n) : # Base cases if (i == n) : return 0; # Checks if a state is already solved if (visit[i][sum + MAX]) : return dp[i][sum + MAX]; visit[i][sum + MAX] = 1; # Recurrence relation dp[i][sum + MAX] = RetClose(arr[i] + MinDiff(i + 1, sum + arr[i], arr, n), MinDiff(i + 1, sum, arr, n), -1 * sum); # Returning the value return dp[i][sum + MAX]; # Function to calculate the closest sum value def FindClose(arr,n) : ans=inf; # Calculate the Closest value for every # subarray arr[i-1:n] for i in range(1, n + 1) : ans = RetClose(arr[i - 1] + MinDiff(i, arr[i - 1], arr, n), ans, 0); print(ans); # Driver function if __name__ == "__main__" : # Input array arr = [ 25, -9, -10, -4, -7, -33 ]; n = len(arr); FindClose(arr,n); # This code is contributed by AnkitRai01 |
C#
// C# Program for above approachusing System;class GFG { static int arrSize = 51;static int maxSum = 201;static int MAX = 100;static int inf = 999999;// Variable to store states of dpstatic int [,]dp = new int [arrSize,maxSum];static int [,]visit = new int [arrSize,maxSum];// Function to return the number // closer to integer sstatic int RetClose(int a, int b, int s){ if (Math.Abs(a - s) < Math.Abs(b - s)) return a; else return b;}// To find the sum closest to zero// Since sum can be negative, we will add MAX// to it to make it positivestatic int MinDiff(int i, int sum, int []arr, int n){ // Base cases if (i == n) return 0; // Checks if a state is already solved if (visit[i,sum + MAX] > 0 ) return dp[i,sum + MAX]; visit[i,sum + MAX] = 1; // Recurrence relation dp[i,sum + MAX] = RetClose(arr[i] + MinDiff(i + 1, sum + arr[i], arr, n), MinDiff(i + 1, sum, arr, n), -1 * sum); // Returning the value return dp[i,sum + MAX];}// Function to calculate the closest sum valuestatic void FindClose(int []arr, int n){ int ans = inf; // Calculate the Closest value for every // subarray arr[i-1:n] for (int i = 1; i <= n; i++) ans = RetClose(arr[i - 1] + MinDiff(i, arr[i - 1], arr, n), ans, 0); Console.WriteLine(ans);}// Driver Codepublic static void Main () { // Input array int []arr = { 25, -9, -10, -4, -7, -33 }; int n = arr.Length; FindClose(arr,n);}}// This code is contributed by anuj_67.. |
Javascript
<script> // Javascript Program for above approach let arrSize = 51; let maxSum = 201; let MAX = 100; let inf = 999999; // Variable to store states of dp let dp = new Array(arrSize); let visit = new Array(arrSize); for(let i = 0; i < arrSize; i++) { dp[i] = new Array(maxSum); visit[i] = new Array(maxSum); for(let j = 0; j < maxSum; j++) { dp[i][j] = 0; visit[i][j] = 0; } } // Function to return the number // closer to integer s function RetClose(a, b, s) { if (Math.abs(a - s) < Math.abs(b - s)) return a; else return b; } // To find the sum closest to zero // Since sum can be negative, we will add MAX // to it to make it positive function MinDiff(i, sum, arr, n) { // Base cases if (i == n) return 0; // Checks if a state is already solved if (visit[i][sum + MAX] > 0 ) return dp[i][sum + MAX]; visit[i][sum + MAX] = 1; // Recurrence relation dp[i][sum + MAX] = RetClose(arr[i] + MinDiff(i + 1, sum + arr[i], arr, n), MinDiff(i + 1, sum, arr, n), -1 * sum); // Returning the value return dp[i][sum + MAX]; } // Function to calculate the closest sum value function FindClose(arr, n) { let ans = inf; // Calculate the Closest value for every // subarray arr[i-1:n] for (let i = 1; i <= n; i++) ans = RetClose(arr[i - 1] + MinDiff(i, arr[i - 1], arr, n), ans, 0); document.write(ans); } // Input array let arr = [ 25, -9, -10, -4, -7, -33 ]; let n = arr.length; FindClose(arr,n);</script> |
-1
Time complexity: O(N*S), where N is the number of elements in the array and S is the sum of all the numbers in the array.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



