The underlying math problem is to split the array to two parts which have closest sum.
The most naive way is a depth first search.
However, a simple depth first search will cause TLE.
To speed up, the following is done.
- Sort array ( this enables de-duplication)
- de-duplication ( this can help on pruning for a lot of cases)
- pruning.
With the above proper pruning applied,
for the case of [1, 1, 1, 1, 1, 1], the dfs will traverse ONLY ONE branch 1, 1, 1, then it will return.
Without pruning, the DFS will search for 2 ^ 6 branches.
class Solution {
public int lastStoneWeightII(int[] stones) {
if (stones.length == 1) return stones[0];
int sum = 0;
for (int n : stones) sum += n;
Arrays.sort(stones); // sort array for de-duplication and for pruning
int[] closest = new int[1];
findClosestFloor(stones, 0, closest, sum / 2, 0);
return sum - 2 * closest[0];
}
private void findClosestFloor(int[] stones, int index, int[] closest, int target, int cur) {
if (closest[0] == target) return; // pruning
if (cur > target) return; // pruning
if (cur > closest[0] && cur <= target) closest[0] = cur;//update result
for (int i = index; i < stones.length; i++) {
if (i != index && stones[i] == stones[i - 1]) continue; // de duplication
findClosestFloor(stones, i + 1, closest, target, cur + stones[i]); // recursion
}
}
}
网友评论