Meta | Phone Screen | Partition Array Into Two Arrays to Minimize Sum Difference Time Complexity
Anonymous User
432

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
}
Comments (3)