I was given the following algorithm for a very similar problem as this one:
https://leetcode.com/problems/partition-array-into-two-arrays-to-minimize-sum-difference/
I am asked to give the time and space complexity for the code below.
const bestJSMeetInMiddle = function (nums) {
const diff = (a,b) => Math.abs(a-b);
const getSum = (x = []) => x.reduce((a,b) => a + b, 0);
const getBisectLeft = (nums, target) => {
let left = 0, right = nums.length;
while (left < right){
const mid = left + Math.floor((right - left) / 2);
if (nums[mid] < target) left = mid + 1;
else right = mid;
}
return left;
}
const createAccumSumObject = (input, i = 0, accum = 0, count = 0, result = new Map()) => {
if (i === input.length){
result.set(count, result.get(count) || []);
result.get(count).push(accum);
return result;
}
createAccumSumObject(input, i + 1, accum + input[i], count + 1, result);
createAccumSumObject(input, i + 1, accum, count, result);
return result;
}
const totalSum = getSum(nums),
halfSum = totalSum /2,
n = nums.length,
setN = Math.floor(n/2),
left = nums.slice(0, setN),
right = nums.slice(setN),
leftAccumMap = createAccumSumObject(left),
rightAccumMap = createAccumSumObject(right);
[...rightAccumMap.keys()].forEach(key => rightAccumMap.get(key).sort((a,b) => a - b));
let minDiff = diff(getSum(left), getSum(right));
for (let leftCount = 1; leftCount < setN; leftCount++){ // for every left count
for (const leftSum of leftAccumMap.get(leftCount)){ // for ecery possible sum
const rightCount = setN - leftCount,
rightList = rightAccumMap.get(rightCount),
target = halfSum - leftSum,
bisectLeftI = getBisectLeft(rightList, target);
for (let rightI = bisectLeftI; rightI >= bisectLeftI - 1 && rightI >= 0; rightI--){ // check left 1 as well since bisect left will go to the next higher value
minDiff = Math.min(minDiff, diff(
leftSum + rightList[rightI],
totalSum - (leftSum + rightList[rightI])
))
}
}
}
return minDiff
}