I have a recursive algorithm that I wrote, which splits an array and finds the minimum of the differences between the two resulting arrays. For example:
If the input array was: [1,2,2,3,3] the minimum difference would be 1. ((1+2+2) - (3+3)). If the input array was: [1,100,4,2] the minimum difference would be 93. (100 - (1+4+2)).
My algorithm is O(2^n) time complexity. I'm trying to use DP with memoization to lower the runtime.
The best that I've achieved is O(2^n / 2) using this memo that prunes half of the recursions, in the worst case. Worst case is that all sums for each level are unique.
How can I do better?
public static int minDiffRecursive(int[] nums) {
int sum = 0;
for(int num : nums) {
sum += num;
}
int[][] memo = new int[nums.length][sum];
for(int[] row : memo) {
Arrays.fill(row, -1);
}
return move(nums, 0, 0, 0, memo);
}
private static int move(int[] nums, int i, int sum1, int sum2, int[][] memo) {
if(i >= nums.length) return Math.abs(sum1 - sum2); //if at the end, return difference
if(memo[i][Math.min(sum1, sum2)] > -1) return memo[i][Math.min(sum1, sum2)]; //take the min of sum1 and sum2, which are mirror images for each i. Return stored value if exists.
int add1 = move(nums, i + 1, sum1 + nums[i], sum2, memo); //check path adding item to sum1
int add2 = move(nums, i + 1, sum1, sum2 + nums[i], memo); //check path adding item to sum2
return memo[i][Math.min(sum1, sum2)] = Math.min(add1, add2); //return the minimum of the two paths
}