Skip to content

1671. Minimum Number of Removals to Make Mountain Array

Description

You may recall that an array arr is a mountain array if and only if:

  • arr.length >= 3
  • There exists some index i (0-indexed) with 0 < i < arr.length - 1 such that:
    • arr[0] < arr[1] < ... < arr[i - 1] < arr[i]
    • arr[i] > arr[i + 1] > ... > arr[arr.length - 1]

Given an integer array nums​​​, return the minimum number of elements to remove to make nums​​​a mountain array.

 

Example 1:

Input: nums = [1,3,1]
Output: 0
Explanation: The array itself is a mountain array so we do not need to remove any elements.

Example 2:

Input: nums = [2,1,1,5,6,2,3,1]
Output: 3
Explanation: One solution is to remove the elements at indices 0, 1, and 5, making the array nums = [1,5,6,3,1].

 

Constraints:

  • 3 <= nums.length <= 1000
  • 1 <= nums[i] <= 109
  • It is guaranteed that you can make a mountain array out of nums.

 

Solutions

Solution: Dynamic Programming + Binary Search

  • Time complexity: O(nlogn)
  • Space complexity: O(n)

 

JavaScript

js
/**
 * @param {number[]} nums
 * @return {number}
 */
const minimumMountainRemovals = function (nums) {
  const n = nums.length;

  const findFirstLargeIndex = (elements, target) => {
    let left = 0;
    let right = elements.length;

    while (left < right) {
      const mid = Math.floor((left + right) / 2);

      elements[mid] >= target ? (right = mid) : (left = mid + 1);
    }
    return left;
  };

  const lengthOfLIS = elements => {
    const result = new Array(n).fill(0);
    const current = [];

    for (let index = 0; index < n; index++) {
      const element = elements[index];
      const firstIndex = findFirstLargeIndex(current, element);

      current[firstIndex] = element;
      result[index] = current.length;
    }
    return result;
  };

  const leftLengthOfLIS = lengthOfLIS(nums);
  const rightLengthOfLIS = lengthOfLIS([...nums].reverse()).reverse();
  let result = 0;

  for (let index = 0; index < n; index++) {
    const left = leftLengthOfLIS[index];
    const right = rightLengthOfLIS[index];

    if (left < 2 || right < 2) continue;

    result = Math.max(left + right - 1, result);
  }
  return n - result;
};

Released under the MIT license