Open In App

Partition a set into two subsets such that the difference of subset sums is minimum

Last Updated : 18 Nov, 2024
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

Given an array arr[] of size n, the task is to divide it into two sets S1 and S2 such that the absolute difference between their sums is minimum
If there is a set S with n elements, then if we assume Subset1 has m elements, Subset2 must have n-m elements and the value of abs(sum(Subset1) - sum(Subset2)) should be minimum.

Example: 

Input: arr = [1, 6, 11, 5]
Output: 1
Explanation: S1 = [1, 5, 6], sum = 12, S2 = [11], sum = 11, Absolute Difference (12 - 11) = 1

Input: arr = [1, 5, 11, 5]
Output: 0
Explanation: S1 = [1, 5, 5], sum = 11, S2 = [11], sum = 11, Absolute Difference (11 - 11) = 0

Using Recursion - O(2^n) Time and O(n) Space

For the recursive approach, there will be two cases:

  • Include the last element in the subset: The new sumCalculated becomes sumCalculated + arr[n-1].
  • Exclude the last element: Keep sumCalculated unchanged.

Mathematically, the recurrence relation is:

findMinDifference(arr, n, sumCalculated) = min(findMinDifference(arr, n-1, sumCalculated), findMinDifference(arr, n-1, sumCalculated + arr[n-1])).

Base Cases:

If n = 0: Return the absolute difference |(sumTotal - sumCalculated) - sumCalculated|.

C++
// C++ Code to partition a set into two 
// subsets such that the difference 
// of subset sums is minimum
#include <bits/stdc++.h>
using namespace std;

// Function to calculate the minimum absolute difference
int findMinDifference(vector<int>& arr, int n, 
                      int sumCalculated, int sumTotal) {
  
    // Base case: if we've considered all elements
    if (n == 0) {
        return abs((sumTotal - sumCalculated) 
                                    - sumCalculated);
    }

    // Include the current element in the subset
    int include = findMinDifference(arr, n - 1, 
                    sumCalculated + arr[n - 1], sumTotal);

    // Exclude the current element from the subset
    int exclude = findMinDifference(arr,
                       n - 1, sumCalculated, sumTotal);

    // Return the minimum of both choices
    return min(include, exclude);
}

// Function to get the minimum difference
int minDifference(vector<int>& arr) {
    int sumTotal = 0;
  
    // Calculate total sum of the array
    for (int num : arr) {
        sumTotal += num;
    }

    // Call recursive function to find 
    // the minimum difference
    return findMinDifference(arr, 
                       arr.size(), 0, sumTotal);
}

int main() {

    vector<int> arr = {1, 6, 11, 5};

    cout << minDifference(arr) << endl;

    return 0;
}
Java
// Java Code to partition a set into two
// subsets such that the difference
// of subset sums is minimum
import java.util.*;

class GfG {

    // Function to calculate the minimum absolute difference
    static int findMinDifference(ArrayList<Integer> arr, int n, 
                                   int sumCalculated, int sumTotal) {
        
        // Base case: if we've considered all elements
        if (n == 0) {
            return Math.abs((sumTotal - sumCalculated) 
                                        - sumCalculated);
        }

        // Include the current element in the subset
        int include = findMinDifference(arr, n - 1, 
                        sumCalculated + arr.get(n - 1), sumTotal);

        // Exclude the current element from the subset
        int exclude = findMinDifference(arr,
                           n - 1, sumCalculated, sumTotal);

        // Return the minimum of both choices
        return Math.min(include, exclude);
    }

    // Function to get the minimum difference
    static int minDifference(ArrayList<Integer> arr) {
        int sumTotal = 0;
        
        // Calculate total sum of the array
        for (int num : arr) {
            sumTotal += num;
        }

        // Call recursive function to find 
        // the minimum difference
        return findMinDifference(arr, 
                           arr.size(), 0, sumTotal);
    }

    public static void main(String[] args) {

        ArrayList<Integer> arr
          = new ArrayList<>(Arrays.asList(1, 6, 11, 5));

        System.out.println(minDifference(arr));
    }
}
Python
# Python Code to partition a set into two
# subsets such that the difference
# of subset sums is minimum

# Function to calculate the minimum absolute difference
def find_min_difference(arr, n, sum_calculated, sum_total):
    
    # Base case: if we've considered all elements
    if n == 0:
        return abs((sum_total - sum_calculated) 
                            - sum_calculated)

    # Include the current element in the subset
    include = find_min_difference(arr, n - 1, 
                    sum_calculated + arr[n - 1], sum_total)

    # Exclude the current element from the subset
    exclude = find_min_difference(arr,
                       n - 1, sum_calculated, sum_total)

    # Return the minimum of both choices
    return min(include, exclude)

# Function to get the minimum difference
def min_difference(arr):
    sum_total = 0
    
    # Calculate total sum of the array
    for num in arr:
        sum_total += num

    # Call recursive function to find 
    # the minimum difference
    return find_min_difference(arr, 
                           len(arr), 0, sum_total)

if __name__ == "__main__":

    arr = [1, 6, 11, 5]

    print(min_difference(arr))
C#
// C# Code to partition a set into two 
// subsets such that the difference 
// of subset sums is minimum
using System;
using System.Collections.Generic;

class GfG {
  
    // Function to calculate the minimum absolute difference
    static int FindMinDifference(List<int> arr, int n, 
                                  int sumCalculated, int sumTotal) {
      
        // Base case: if we've considered all elements
        if (n == 0) {
            return Math.Abs((sumTotal - sumCalculated) 
                                    - sumCalculated);
        }

        // Include the current element in the subset
        int include = FindMinDifference(arr, n - 1, 
                    sumCalculated + arr[n - 1], sumTotal);

        // Exclude the current element from the subset
        int exclude = FindMinDifference(arr,
                       n - 1, sumCalculated, sumTotal);

        // Return the minimum of both choices
        return Math.Min(include, exclude);
    }

    // Function to get the minimum difference
    static int MinDifference(List<int> arr) {
        int sumTotal = 0;

        // Calculate total sum of the array
        foreach (int num in arr) {
            sumTotal += num;
        }

        // Call recursive function to find 
        // the minimum difference
        return FindMinDifference(arr, 
                       arr.Count, 0, sumTotal);
    }

    static void Main() {
        List<int> arr = new List<int>{1, 6, 11, 5};

        Console.WriteLine(MinDifference(arr));
    }
}
JavaScript
// JavaScript code to partition a set into two 
// subsets such that the difference 
// of subset sums is minimum

// Function to calculate the minimum absolute difference
function findMinDifference(arr, n, sumCalculated, sumTotal) {

    // Base case: if we've considered all elements
    if (n === 0) {
        return Math.abs((sumTotal - sumCalculated) 
                                    - sumCalculated);
    }

    // Include the current element in the subset
    let include = findMinDifference(arr, n - 1, 
                    sumCalculated + arr[n - 1], sumTotal);

    // Exclude the current element from the subset
    let exclude = findMinDifference(arr, 
                    n - 1, sumCalculated, sumTotal);

    // Return the minimum of both choices
    return Math.min(include, exclude);
}

// Function to get the minimum difference
function minDifference(arr) {
    let sumTotal = 0;

    // Calculate total sum of the array
    for (let num of arr) {
        sumTotal += num;
    }

    // Call recursive function to find 
    // the minimum difference
    return findMinDifference(arr, arr.length, 0, sumTotal);
}

let arr = [1, 6, 11, 5];
console.log(minDifference(arr));

Output
1

Using Top-Down DP (Memoization) - O(n*sumTotal) Time and O(n*sumTotal) Space

In this problem, we can observe that the recursive solution holds the following two properties of Dynamic Programming:

1. Optimal Substructure: If the last element (arr[n-1]) is greater than the current sumCalculated, we cannot include it:

  • findMinDifference(arr, n, sumCalculated) = findMinDifference(arr, n-1, sumCalculated)

Otherwise, we have two choices:

  • Include it: findMinDifference(arr, n, sumCalculated) = findMinDifference(arr, n-1, sumCalculated + arr[n-1])
  • Exclude it: findMinDifference(arr, n, sumCalculated) = findMinDifference(arr, n-1, sumCalculated)

2. Overlapping Subproblems: Many subproblems are solved multiple times during recursion. Using a 2D memoization table of size (n+1) x (sumTotal+1), we store solutions for subproblems to avoid recomputation. Initialize all values to -1.

  • If memo[n][sumCalculated] != -1, use the stored value.
C++
// C++ Code to partition a set into two 
// subsets such that the difference 
// of subset sums is minimum, using memoization
#include <bits/stdc++.h>
using namespace std;

// Function to calculate the minimum absolute 
// difference with memoization
int findMinDifference(vector<int>& arr, int n, 
                      int sumCalculated, int sumTotal, 
                      vector<vector<int>>& memo) {

    // Base case: if we've considered all elements
    if (n == 0) {
        return abs((sumTotal - sumCalculated) 
                                    - sumCalculated);
    }

    // Check if the result is already computed
    if (memo[n][sumCalculated] != -1) {
        return memo[n][sumCalculated];
    }

    // Include the current element in the subset
    int include = findMinDifference(arr, n - 1, 
                    sumCalculated + arr[n - 1], sumTotal, memo);

    // Exclude the current element from the subset
    int exclude = findMinDifference(arr, n - 1, 
                    sumCalculated, sumTotal, memo);

    // Store the result in memo and return
    return memo[n][sumCalculated] = min(include, exclude);
}

// Function to get the minimum difference
int minDifference(vector<int>& arr) {
    int sumTotal = 0;

    // Calculate total sum of the array
    for (int num : arr) {
        sumTotal += num;
    }

    // Create a 2D memoization table, initialized to -1
    vector<vector<int>> memo(arr.size() + 1, 
                             vector<int>(sumTotal + 1, -1));

    // Call the recursive function with memoization
    return findMinDifference(arr, arr.size(), 
                               0, sumTotal, memo);
}

int main() {

    vector<int> arr = {1, 6, 11, 5};

    cout << minDifference(arr) << endl;

    return 0;
}
Java
// Java Code to partition a set into two
// subsets such that the difference
// of subset sums is minimum using memoization
import java.util.*;

 class GfG {

    // Function to calculate the minimum absolute 
    // difference with memoization
    static int findMinDifference(ArrayList<Integer> arr, int n,
                                 int sumCalculated, int sumTotal, 
                                 int[][] memo) {
        
        // Base case: if we've considered all elements
        if (n == 0) {
            return Math.abs((sumTotal - sumCalculated)
                            - sumCalculated);
        }

        // Check if result is already computed
        if (memo[n][sumCalculated] != -1) {
            return memo[n][sumCalculated];
        }

        // Include the current element in the subset
        int include = findMinDifference(arr, n - 1,
                        sumCalculated + arr.get(n - 1), 
                        sumTotal, memo);

        // Exclude the current element from the subset
        int exclude = findMinDifference(arr, n - 1,
                                         sumCalculated, sumTotal, memo);

        // Store the result in memo and return
        memo[n][sumCalculated] = Math.min(include, exclude);
        return memo[n][sumCalculated];
    }

    // Function to get the minimum difference
    static int minDifference(ArrayList<Integer> arr) {
        int sumTotal = 0;

        // Calculate total sum of the array
        for (int num : arr) {
            sumTotal += num;
        }

        // Create a memoization table initialized to -1
        int[][] memo = new int[arr.size() + 1][sumTotal + 1];
        for (int[] row : memo) {
            Arrays.fill(row, -1);
        }

        // Call the recursive function with memoization
        return findMinDifference(arr, arr.size(), 0, sumTotal, memo);
    }

    public static void main(String[] args) {

        ArrayList<Integer> arr
          = new ArrayList<>(Arrays.asList(1, 6, 11, 5));

        System.out.println(minDifference(arr));
    }
}
Python
# Python Code to partition a set into two
# subsets such that the difference
# of subset sums is minimum using memoization

# Function to calculate the minimum absolute
# difference with memoization
def find_min_difference(arr, n, sum_calculated, sum_total, memo):
    
    # Base case: if we've considered all elements
    if n == 0:
        return abs((sum_total - sum_calculated) 
                            - sum_calculated)

    # Check if result is already computed
    if memo[n][sum_calculated] != -1:
        return memo[n][sum_calculated]

    # Include the current element in the subset
    include = find_min_difference(arr, n - 1, 
                    sum_calculated + arr[n - 1], sum_total, memo)

    # Exclude the current element from the subset
    exclude = find_min_difference(arr, n - 1, 
                                   sum_calculated, sum_total, memo)

    # Store the result in memo and return
    memo[n][sum_calculated] = min(include, exclude)
    return memo[n][sum_calculated]

# Function to get the minimum difference
def min_difference(arr):
    sum_total = sum(arr) 
    
    # Create a memoization table initialized to -1
    memo = [[-1 for _ in range(sum_total + 1)] for _ in range(len(arr) + 1)]

    # Call the recursive function with memoization
    return find_min_difference(arr, len(arr), 0, sum_total, memo)

if __name__ == "__main__":
    arr = [1, 6, 11, 5]
    print(min_difference(arr))
C#
// C# Code to partition a set into two 
// subsets such that the difference 
// of subset sums is minimum using memoization
using System;
using System.Collections.Generic;

class GfG {

    // Function to calculate the minimum absolute 
    // difference with memoization
    static int FindMinDifference(List<int> arr, int n, 
                                  int sumCalculated, int sumTotal, 
                                  int[,] memo) {
      
        // Base case: if we've considered all elements
        if (n == 0) {
            return Math.Abs((sumTotal - sumCalculated) 
                                    - sumCalculated);
        }

        // Check if result is already computed
        if (memo[n, sumCalculated] != -1) {
            return memo[n, sumCalculated];
        }

        // Include the current element in the subset
        int include = FindMinDifference(arr, n - 1, 
                    sumCalculated + arr[n - 1], sumTotal, memo);

        // Exclude the current element from the subset
        int exclude = FindMinDifference(arr, 
                       n - 1, sumCalculated, sumTotal, memo);

        // Store the result in memo and return
        memo[n, sumCalculated] = Math.Min(include, exclude);
        return memo[n, sumCalculated];
    }

    // Function to get the minimum difference
    static int MinDifference(List<int> arr) {
        int sumTotal = 0;

        // Calculate total sum of the array
        foreach (int num in arr) {
            sumTotal += num;
        }

        // Create a memoization table initialized to -1
        int[,] memo = new int[arr.Count + 1, sumTotal + 1];
        for (int i = 0; i <= arr.Count; i++) {
            for (int j = 0; j <= sumTotal; j++) {
                memo[i, j] = -1;
            }
        }

        // Call recursive function to find 
        // the minimum difference
        return FindMinDifference(arr, 
                       arr.Count, 0, sumTotal, memo);
    }

    static void Main() {
        List<int> arr = new List<int>{1, 6, 11, 5};

        Console.WriteLine(MinDifference(arr));
    }
}
JavaScript
// JavaScript code to partition a set into two 
// subsets such that the difference 
// of subset sums is minimum using memoization

// Function to calculate the minimum absolute difference
function findMinDifference(arr, n, 
                sumCalculated, sumTotal, memo) {

    // Base case: if we've considered all elements
    if (n === 0) {
        return Math.abs((sumTotal - sumCalculated) 
                                    - sumCalculated);
    }

    // Check if result is already computed
    if (memo[n][sumCalculated] !== -1) {
        return memo[n][sumCalculated];
    }

    // Include the current element in the subset
    let include = findMinDifference(arr, n - 1, 
                    sumCalculated + arr[n - 1], sumTotal, memo);

    // Exclude the current element from the subset
    let exclude = findMinDifference(arr, 
                    n - 1, sumCalculated, sumTotal, memo);

    // Store the result in memo and return
    memo[n][sumCalculated] = Math.min(include, exclude);
    return memo[n][sumCalculated];
}

// Function to get the minimum difference
function minDifference(arr) {
    let sumTotal = 0;

    // Calculate total sum of the array
    for (let num of arr) {
        sumTotal += num;
    }

    // Create a memoization table initialized to -1
    let memo = Array(arr.length + 1).fill(null).map(() =>
        Array(sumTotal + 1).fill(-1)
    );

    // Call recursive function to find 
    // the minimum difference
    return findMinDifference(arr, arr.length, 0, sumTotal, memo);
}

let arr = [1, 6, 11, 5];
console.log(minDifference(arr));

Output
1

Using Bottom-Up DP (Tabulation) - O(n*sumTotal) Time and O(n*sumTotal) Space

This approach iteratively builds the solution in a bottom-up manner instead of solving it recursively. We use a 2D DP table of size (n + 1) x (sumTotal + 1) where: dp[i][j] = true if a subset of elements from arr[0...i] has a sum of j.

If the current element (arr[i-1]) is greater than the sum j:

  • dp[i][j] = dp[i-1][j]

Otherwise, we check:

  • Include the element: dp[i-1][j - arr[i-1]]
  • Exclude the element: dp[i-1][j]

Final result: dp[i][j] = dp[i-1][j] || dp[i-1][j - arr[i-1]]

C++
// C++ Code to partition a set into two 
// subsets such that the difference 
// of subset sums is minimum, using Tabulation
#include <bits/stdc++.h>
using namespace std;

// Function to calculate the minimum absolute 
// difference using tabulation
int minDifference(vector<int>& arr) {
    int sumTotal = 0;

    // Calculate total sum of the array
    for (int num : arr) {
        sumTotal += num;
    }

    int n = arr.size();

    // Create a 2D DP table initialized to 0 
  	// (since it's an int array)
    vector<vector<int>> dp(n + 1, vector<int>(sumTotal + 1, 0));

    // Sum of 0 is always achievable, initialize dp[0][0] = 1
    dp[0][0] = 1;

    // Fill the DP table
    for (int i = 1; i <= n; i++) {
        for (int sum = 0; sum <= sumTotal; sum++) {
          
            // Exclude the current element
            dp[i][sum] = dp[i-1][sum];
            
            // Include the current element if sum >= arr[i-1]
            if (sum >= arr[i-1]) {
                dp[i][sum] = dp[i][sum] || dp[i-1][sum - arr[i-1]];
            }
        }
    }

    // Find the minimum difference
    int minDiff = INT_MAX;

    // Iterate over all possible subset sums and
    // find the minimum difference
    for (int sum = 0; sum <= sumTotal / 2; sum++) {
        if (dp[n][sum]) {
            minDiff = min(minDiff, abs((sumTotal - sum) - sum));
        }
    }

    return minDiff;
}

int main() {
    vector<int> arr = {1, 6, 11, 5};

    cout << minDifference(arr) << endl;

    return 0;
}
Java
// Java Code to partition a set into two 
// subsets such that the difference 
// of subset sums is minimum, using Tabulation
import java.util.*;

class GfG {

    // Function to get the minimum difference 
    // using tabulation
    static int minDifference(ArrayList<Integer> arr) {
        int sumTotal = 0;

        // Calculate total sum of the array
        for (int num : arr) {
            sumTotal += num;
        }

        int n = arr.size();

        // Create a DP table where dp[i][j] represents
        // if a subset sum 'j' is achievable 
        // using the first 'i' elements
        boolean[][] dp = new boolean[n + 1][sumTotal + 1];

        // A sum of 0 is always achievable (empty subset)
        dp[0][0] = true;

        // Fill the DP table
        for (int i = 1; i <= n; i++) {
            for (int sum = 0; sum <= sumTotal; sum++) {
              
                // Exclude the current element
                dp[i][sum] = dp[i - 1][sum];

                // Include the current element if sum >= arr[i-1]
                if (sum >= arr.get(i - 1)) {
                    dp[i][sum] = dp[i][sum] 
                          || dp[i - 1][sum - arr.get(i - 1)];
                }
            }
        }

        // Find the minimum difference
        int minDiff = Integer.MAX_VALUE;

        // Iterate over all possible subset sums
        // and find the minimum difference
        for (int sum = 0; sum <= sumTotal / 2; sum++) {
            if (dp[n][sum]) {
                minDiff = Math.min(minDiff,
                                 Math.abs((sumTotal - sum) - sum));
            }
        }

        return minDiff;
    }

    public static void main(String[] args) {
        ArrayList<Integer> arr 
             = new ArrayList<>(Arrays.asList(1, 6, 11, 5));

        System.out.println(minDifference(arr));
    }
}
Python
# Python Code to partition a set into two
# subsets such that the difference
# of subset sums is minimum using tabulation

# Function to get the minimum difference
# using tabulation
def min_difference(arr):
    sum_total = sum(arr)

    n = len(arr)

    # Create a DP table where dp[i][j] represents if a subset
    # sum 'j' is achievable using the first 'i' elements
    dp = [[False for _ in range(sum_total + 1)] for _ in range(n + 1)]

    # A sum of 0 is always achievable (empty subset)
    dp[0][0] = True

    # Fill the DP table
    for i in range(1, n + 1):
        for sum_val in range(0, sum_total + 1):
            # Exclude the current element
            dp[i][sum_val] = dp[i - 1][sum_val]

            # Include the current element if sum_val >= arr[i-1]
            if sum_val >= arr[i - 1]:
                dp[i][sum_val] = dp[i][sum_val] \
                        or dp[i - 1][sum_val - arr[i - 1]]

    # Find the minimum difference
    min_diff = float('inf')

    # Iterate over all possible subset sums and 
    # find the minimum difference
    for sum_val in range(0, sum_total // 2 + 1):
        if dp[n][sum_val]:
            min_diff = min(min_diff, \
                      abs((sum_total - sum_val) - sum_val))

    return min_diff


if __name__ == "__main__":
  
    arr = [1, 6, 11, 5]
    print(min_difference(arr))
C#
// C# Code to partition a set into two 
// subsets such that the difference 
// of subset sums is minimum, using Tabulation
using System;
using System.Collections.Generic;

class GfG {

    // Function to get the minimum difference 
    // using tabulation
    static int MinDifference(List<int> arr) {
        int sumTotal = 0;

        // Calculate total sum of the array
        foreach (int num in arr) {
            sumTotal += num;
        }

        int n = arr.Count;

        // Create a DP table where dp[i][j] represents 
        // if a subset sum 'j' is achievable using the 
        // first 'i' elements
        bool[,] dp = new bool[n + 1, sumTotal + 1];

        // A sum of 0 is always achievable (empty subset)
        dp[0, 0] = true;

        // Fill the DP table
        for (int i = 1; i <= n; i++) {
            for (int sum = 0; sum <= sumTotal; sum++) {
              
                // Exclude the current element
                dp[i, sum] = dp[i - 1, sum];

                // Include the current element if sum >= arr[i - 1]
                if (sum >= arr[i - 1]) {
                    dp[i, sum] |= dp[i - 1, sum - arr[i - 1]];
                }
            }
        }

        // Find the minimum difference
        int minDiff = int.MaxValue;

        // Iterate over all possible subset sums 
        // and find the minimum difference
        for (int sum = 0; sum <= sumTotal / 2; sum++) {
            if (dp[n, sum]) {
                minDiff = Math.Min(minDiff, 
                                   Math.Abs((sumTotal - sum) - sum));
            }
        }

        return minDiff;
    }

    static void Main() {
        List<int> arr = new List<int> { 1, 6, 11, 5 };

        Console.WriteLine(MinDifference(arr));
    }
}
JavaScript
// Javascript Code to partition a set into two 
// subsets such that the difference 
// of subset sums is minimum, using Tabulation

// Function to get the minimum difference using tabulation
function minDifference(arr) {
    let sumTotal = 0;

    // Calculate total sum of the array
    for (let num of arr) {
        sumTotal += num;
    }

    let n = arr.length;

    // Create a DP table where dp[i][j] represents 
    // if a subset sum 'j' is achievable using 
    // the first 'i' elements
    let dp = Array(n + 1).fill(null).map(() => Array(sumTotal + 1).fill(false));

    // A sum of 0 is always achievable (empty subset)
    dp[0][0] = true;

    // Fill the DP table
    for (let i = 1; i <= n; i++) {
        for (let sum = 0; sum <= sumTotal; sum++) {
        
            // Exclude the current element
            dp[i][sum] = dp[i - 1][sum];

            // Include the current element if sum >= arr[i - 1]
            if (sum >= arr[i - 1]) {
                dp[i][sum] = dp[i][sum] 
                        || dp[i - 1][sum - arr[i - 1]];
            }
        }
    }

    // Find the minimum difference
    let minDiff = Number.MAX_VALUE;

    // Iterate over all possible subset sums and 
    // find the minimum difference
    for (let sum = 0; sum <= sumTotal / 2; sum++) {
        if (dp[n][sum]) {
            minDiff = Math.min(minDiff, 
                   Math.abs((sumTotal - sum) - sum));
        }
    }

    return minDiff;
}

let arr = [1, 6, 11, 5];
console.log(minDifference(arr));

Output
1

Using Space Optimized DP - O(n*sumTotal) Time and O(sumTotal) Space

In the previous approach, we derived the relation between states as follows:

if (arr[i-1] > j)

dp[i][j] = dp[i-1][j]

else

dp[i][j] = dp[i-1][j] || dp[i-1][j-arr[i-1]]

Here, for calculating the current state dp[i][j], we only require values from the previous row: dp[i-1][j] and dp[i-1][j-arr[i-1]]. This observation eliminates the need to store the entire DP table, as only the previous row is needed to compute the current one. Use a single 1D array (dp) of size sumTotal + 1 to store achievable subset sums.

dp[j] = dp[j] || dp[j - arr[i-1]];

C++
// C++ code to partition a set into two subsets
// with min diff with space optimization
#include <bits/stdc++.h>
using namespace std;

// Function to get the minimum difference using 
// space optimization
int minDifference(vector<int>& arr) {
   int sumTotal = 0;

    // Calculate total sum of the array
    for (int num : arr) {
        sumTotal += num;
    }

    // Create a 1D DP array to track achievable subset sums
    vector<bool> dp(sumTotal + 1, false);
    dp[0] = true; 

    // Fill the DP array
    for (int num : arr) {
        for (int sum = sumTotal; sum >= num; sum--) {
            dp[sum] = dp[sum] || dp[sum - num];
        }
    }

    // Find the minimum difference
    int minDiff = sumTotal;
    for (int sum = 0; sum <= sumTotal / 2; sum++) {
        if (dp[sum]) {
            minDiff = min(minDiff, abs((sumTotal - sum) - sum));
        }
    }

    return minDiff;
}

int main() {
    vector<int> arr = {1, 6, 11, 5};

    cout << minDifference(arr) << endl;

    return 0;
}
Java
// Java code to partition a set into two subsets
// with min diff with space optimization
import java.util.*;

class GfG {

    // Function to get the minimum difference 
    // using space optimization
    static int minDifference(List<Integer> arr) {
        int sumTotal = 0;

        // Calculate total sum of the array
        for (int num : arr) {
            sumTotal += num;
        }

        // Create a 1D DP array to track 
      	// achievable subset sums
        boolean[] dp = new boolean[sumTotal + 1];
        dp[0] = true; 

        // Fill the DP array
        for (int num : arr) {
            for (int sum = sumTotal; sum >= num; sum--) {
                dp[sum] = dp[sum] || dp[sum - num];
            }
        }

        // Find the minimum difference
        int minDiff = sumTotal;
        for (int sum = 0; sum <= sumTotal / 2; sum++) {
            if (dp[sum]) {
                minDiff = Math.min(minDiff,
                                  Math.abs((sumTotal - sum) - sum));
            }
        }

        return minDiff;
    }

    public static void main(String[] args) {
        List<Integer> arr = Arrays.asList(1, 6, 11, 5);

        System.out.println(minDifference(arr));
    }
}
Python
# Python code to partition a set into two subsets
# with min diff with space optimization
def min_difference(arr):
    sum_total = sum(arr)

    # Create a 1D DP array to track 
    # achievable subset sums
    dp = [False] * (sum_total + 1)
    dp[0] = True  

    # Fill the DP array
    for num in arr:
        for sum_val in range(sum_total, num - 1, -1):
            dp[sum_val] = dp[sum_val] or dp[sum_val - num]

    # Find the minimum difference
    min_diff = sum_total
    for sum_val in range(sum_total // 2 + 1):
        if dp[sum_val]:
            min_diff = min(min_diff, abs((sum_total - sum_val) - sum_val))

    return min_diff

arr = [1, 6, 11, 5]
print(min_difference(arr))
C#
// C# code to partition a set into two subsets
// with min diff with space optimization
using System;
using System.Collections.Generic;

class GfG {

    // Function to get the minimum difference 
    // using space optimization
    static int MinDifference(List<int> arr) {
        int sumTotal = 0;

        // Calculate total sum of the array
        foreach (int num in arr) {
            sumTotal += num;
        }

        // Create a 1D DP array to 
      	// track achievable subset sums
        bool[] dp = new bool[sumTotal + 1];
        dp[0] = true; 

        // Fill the DP array
        foreach (int num in arr) {
            for (int sum = sumTotal; sum >= num; sum--) {
                dp[sum] = dp[sum] || dp[sum - num];
            }
        }

        // Find the minimum difference
        int minDiff = sumTotal;
        for (int sum = 0; sum <= sumTotal / 2; sum++) {
            if (dp[sum]) {
                minDiff = Math.Min(minDiff, 
                                   Math.Abs((sumTotal - sum) - sum));
            }
        }

        return minDiff;
    }

    static void Main() {
        List<int> arr = new List<int>{1, 6, 11, 5};

        Console.WriteLine(MinDifference(arr));
    }
}
JavaScript
// JavaScript code to partition a set into two subsets
// with min diff with space optimization
function minDifference(arr) {
    let sumTotal = arr.reduce((sum, num) => sum + num, 0);

    // Create a 1D DP array to track achievable subset sums
    let dp = new Array(sumTotal + 1).fill(false);
    dp[0] = true; 

    // Fill the DP array
    for (let num of arr) {
        for (let sumVal = sumTotal; sumVal >= num; sumVal--) {
            dp[sumVal] = dp[sumVal] || dp[sumVal - num];
        }
    }

    // Find the minimum difference
    let minDiff = sumTotal;
    for (let sumVal = 0; sumVal <= sumTotal / 2; sumVal++) {
        if (dp[sumVal]) {
            minDiff = Math.min(minDiff, 
               Math.abs((sumTotal - sumVal) - sumVal));
        }
    }

    return minDiff;
}

let arr = [1, 6, 11, 5];
console.log(minDifference(arr));

Output
1

Similar Reads