📌  相关文章
📜  通过删除最小数量的元素将给定的数组设为 Mountain 数组(1)

📅  最后修改于: 2023-12-03 14:58:04.442000             🧑  作者: Mango

通过删除最小数量的元素将给定的数组设为 Mountain 数组

Mountain 数组的定义是这样的:一个数组 A 就是一个 Mountain 数组需满足:

  • A.length >= 3
  • 存在 0 < i < A.length - 1,使得:
  • A[0] < A[1] < ... A[i-1] < A[i]
  • A[i] > A[i+1] > ... > A[A.length - 1]

也就是说,一个 Mountain 数组应该是这样的一种形状:

   /\
  /  \
 /    \
/      \

要通过删除最小数量的元素将给定的数组设为 Mountain 数组,我们需要进行如下的步骤:

  1. 找到数组中最高峰的位置 i。
  2. 找到 A[0] 到 A[i] 的最大值 max1,A[i] 到 A[A.length - 1] 的最大值 max2。
  3. 如果 max1 和 max2 的值都是 A[i],那么就说明 A 是一个 Mountain 数组,并且不需要删除元素。
  4. 如果 max1 和 max2 的值中至少有一个不是 A[i],那么我们就需要删除若干个元素,使得 A[0] 到 A[i] 的最大值等于 A[i],A[i] 到 A[A.length - 1] 的最大值等于 A[i]。

这个时候,我们就可以用贪心算法来处理。具体来说,我们可以从左边开始遍历数组,用一个变量 left 记录当前的位置,用一个变量 right 记录最高峰的位置 i。如果我们遍历到某个位置 j,发现 A[j] 比 A[left] 小,那么就需要删除 A[left] 到 A[j-1] 这些元素,使得 A[left] 变成当前位置 j 的元素。这个时候我们可以更新 right 的值,保证 right 一直指向最高峰的位置。

反之,如果 A[j] 不比 A[left] 小,那么我们就可以更新 left 的值为 j,并继续向右遍历。

最终,left 和 right 之间的元素就是需要删除的元素。

下面是一个 Python 的实现:

from typing import List


def make_mountain_array(nums: List[int]) -> int:
    n = len(nums)
    if n < 3:
        return 0

    # Step 1: 找到数组中最高峰的位置 i
    i = max(range(n), key=lambda x: nums[x])

    # Step 2: 找到 A[0] 到 A[i] 的最大值和 A[i] 到 A[n-1] 的最大值
    max1 = max(nums[:i + 1])
    max2 = max(nums[i:])

    # Step 3: 如果已经是 Mountain 数组了,那么就不用删除了
    if max1 == max2 == nums[i]:
        return 0

    # Step 4: 使用贪心算法,找到需要删除的位置
    left, right = 0, i
    ans = 0
    for j in range(1, n):
        if nums[j] < nums[left]:
            ans += right - left
            left = j
            right = i
        elif nums[j] > nums[right]:
            right = j

    ans += right - left

    return ans

以上就是我们的算法实现了。该算法的时间复杂度为 $O(n)$,其中 n 是数组的长度。