The problem is the following:
You are given a set of positive integers { a1 , a2 , a3 , ... , an } in which there are no same numbers ( a1 exists only once ,a2 exist
No problem, here's an O(1)
solution.
A1 = {};
A2 = {};
sum(A1) == sum(A2) /* == 0 */
QED.
Seriously, one optimization you can make (assuming that we're talking about positive numbers) is to only check sub-sets less or equal to sum(A)/2
.
For every element in A
there are three options which makes it O(3^N)
:
A1
A2
Here's a naive solution in Perl (that counts the matches, you can have an early return if you just want to test existence).
use List::Util qw/sum/;
my $max = sum(@ARGV)/2;
my $first = shift(@ARGV); # make sure we don't find the empty set (all joking aside) and that we don't cover same solution twice (since elements are unique)
my $found = find($first,0, @ARGV);
print "Number of matches: $found\n";
sub find {
my ($a, $b, @tail) = @_;
my $ret = $a == $b? 1 : 0; # are a and b equal sub-sets?
return $ret unless @tail;
my $x = shift @tail;
$ret += find($a + $x, $b, @tail) if $a + $x <= $max; # put x in a
$ret += find($a, $b + $x, @tail) if $b + $x <= $max; # put x in b
return $ret + find($a, $b, @tail); # discard x
}