Partition into Two Equal-Sum Subsets

Problem

Print true if the array can be split into two groups (every element in exactly one group) with the same sum. Otherwise print false.

Constraints

  • 1 <= n <= 200
  • 1 <= a[i] <= 100

Examples

Input

4
1 5 11 5

Output

true

Solutions

Best approachTime O(n * total)Space O(total)

This is the subset-sum problem for the target total / 2. Going from big sums to small sums matters: with the forward order one element could be used twice.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Process an array.
 * Input   : n, then n integers.
 * Output  : true or false.
 * Approach: Subset-sum table.
 * Time    : O(n * total)
 * Space   : O(total)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
    // This method solves the task. It receives the input and returns the answer.
    static boolean solve(int[] a) {
        // Step 1: If the total is odd, two equal halves are impossible.
        int total = 0;
        for (int value : a) {
            total += value;
        }
        if (total % 2 != 0) {
            return false;
        }

        // Step 2: reachable[s] is true if some group of elements has the sum s. The sum 0 is always possible (empty group).
        int target = total / 2;
        boolean[] reachable = new boolean[target + 1];
        reachable[0] = true;

        // Step 3: For each element, update the sums from big to small, so one element is used at most once.
        for (int value : a) {
            for (int sum = target; sum >= value; sum--) {
                if (reachable[sum - value]) {
                    reachable[sum] = true;
                }
            }
        }
        return reachable[target];
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int size = scanner.nextInt();
        int[] a = new int[size];
        for (int i = 0; i < size; i++) {
            a[i] = scanner.nextInt();
        }
        System.out.println(solve(a));
    }
}
Hints (1)
  1. Why is the inner loop backwards?