Difficulty
Hard


Split Array Largest Sum (opens in a new tab)

  • Use binary searach with min & max as max & sum of the array
  • Check if the sum can be split into k subarrays for mid value
/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
var splitArray = function (nums, k) {
  const [sum, max] = getTotalAndMax(nums);
  if (k === nums.length) {
    return max;
  }
 
  if (k === 1) {
    return sum;
  }
 
  let left = max,
    right = sum,
    ans = 0;
  while (left <= right) {
    const mid = left + Math.floor((right - left) / 2);
    const canFit = checkFitment(nums, k, mid);
 
    if (canFit) {
      ans = mid;
      right = mid - 1;
    } else {
      left = mid + 1;
    }
  }
 
  return ans;
};
 
function checkFitment(nums, k, limit) {
  let sum = 0,
    count = 1;
  for (let i = 0; i < nums.length; i++) {
    sum += nums[i];
    if (sum > limit) {
      count += 1;
      sum = nums[i];
 
      if (count > k) {
        return false;
      }
    }
  }
 
  return true;
}
 
function getTotalAndMax(arr) {
  let sum = 0,
    max = 0;
 
  for (const item of arr) {
    sum += item;
    if (max < item) {
      max = item;
    }
  }
 
  return [sum, max];
}
Complexity
  • Time: O(n log(sum - max))
  • Space: O(1)


Minimize Max Distance to Gas Station (opens in a new tab)

  • For a binary search, use left as minimum distance possible and right as maximum distance possible
  • For each distance, check if it is possible to add k stations with gap less than or equal to the distance
/**
 * @param {number[]} stations
 * @param {number} k
 * @return {number}
 */
var minmaxGasDist = function (stations, k) {
  let left = 0, right = stations.at(-1) - stations.at(0);
 
  while (right - left > 1e-6) {
    const mid = left + (right - left) / 2;
    const canFit = checkEligibleGap(stations, k, mid);
 
    if (canFit) {
      right = mid;
    } else {
      left = mid;
    }
  }
 
  return left;
};
 
function checkEligibleGap(stations, k, gap) {
  let newStations = 0;
 
  for (let i = 0; i < stations.length - 1; i++) {
    newStations += Math.ceil((stations[i + 1] - stations[i]) / gap) - 1;
 
    if (newStations > k) {
      return false;
    }
  }
 
  return true;
}
Complexity
  • Time: O(n log(W)) where W is the range of the answer
  • Space: O(1)


Minimum Number of Operations to Make Array Continuous (opens in a new tab)

  • Sort the given nums array by removing duplicates
  • Consider each element as the first element & find the number of elements that can be included in the subarray till the last
  • Consider the rest of the elements count as number of operations required
/**
 * @param {number[]} nums
 * @return {number}
 */
var minOperations = function (nums) {
  const uniqNums = [...new Set(nums)].sort((a, b) => a - b);
 
  // check if already continuous
  if (uniqNums.at(-1) - uniqNums[0] === 1) {
    return 0;
  }
 
  let minOps = nums.length;
  for (let idx = 0; idx < uniqNums.length; idx++) {
    const first = uniqNums[idx];
    const last = first + nums.length - 1; // last element to make it continuous
 
    const lastIdx = getUpperBound(uniqNums, last);
    const sortedCount = lastIdx - idx; // number of elements that are already present to make it continuous
    const ops = nums.length - sortedCount; // number of elements that need to be replaced
 
    minOps = Math.min(minOps, ops);
  }
 
  return minOps;
};
 
function getUpperBound(arr, k) {
  let left = 0, right = arr.length, ans = arr.length;
 
  while (left <= right) {
    const mid = left + Math.floor((right - left) / 2);
 
    if (k < arr[mid]) {
      ans = mid;
      right = mid - 1;
    } else {
      left = mid + 1;
    }
  }
 
  return ans;
}
Complexity
  • Time: O(n log(n))
  • Space: O(n)