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 dp int dp[arrSize][maxSum]; bool visit[arrSize][maxSum]; // Function to return the number closer to integer s int 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 positive 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]) 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 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); cout<<ans<<endl; } // Driver function int 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 approach import 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 dp static int dp[][] = new int [arrSize][maxSum]; static int visit[][] = new int [arrSize][maxSum]; // Function to return the number // closer to integer s static 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 positive static 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 value static 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 Code public 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 implementation import numpy as np arrSize = 51 maxSum = 201 MAX = 100 inf = 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 approach using System; class GFG { static int arrSize = 51; static int maxSum = 201; static int MAX = 100; static int inf = 999999; // Variable to store states of dp static int [,]dp = new int [arrSize,maxSum]; static int [,]visit = new int [arrSize,maxSum]; // Function to return the number // closer to integer s static 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 positive static 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 value static 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 Code public 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 neveropen!