can[0] = true; for each x, for s from half down to x: can[s] |= can[s − x].
Approach 1
class Solution {
public boolean canPartition(int[] nums) {
int total = 0;
for (int x : nums) total += x;
if (total % 2 == 1) return false;
int half = total / 2;
boolean[] can = new boolean[half + 1];
can[0] = true;
for (int x : nums)
for (int s = half; s >= x; s--) can[s] |= can[s - x];
return can[half];
}
}
Verdict: sum ≤ 20 000 keeps it small.
2
Bitset
Time O(n × sum / 64) Space O(sum / 64)
Bit s of a BitSet means "sum s reachable". For each x: bits |= bits << x.
Approach 2
import java.math.BigInteger;
class Solution {
public boolean canPartition(int[] nums) {
int total = 0;
for (int x : nums) total += x;
if (total % 2 == 1) return false;
BigInteger bits = BigInteger.ONE;
for (int x : nums) bits = bits.or(bits.shiftLeft(x));
return bits.testBit(total / 2);
}
}
Verdict: Word-level parallelism; a nice trick for larger sums.