📅  最后修改于: 2023-12-03 15:25:21.822000             🧑  作者: Mango
Mountain Array 是指数组 A 满足:
题目描述:
给你一个整数数组 nums,请你返回将该数组转换为 Mountain Array 所需的最小操作次数。
如果不可行,则返回 -1。
为了更好的解释本题的思路,这里先定义下什么是Mountain Array。
Mountain Array 是指一个数组满足:
存在左侧的 i ,满足 arr[i] < arr[i + 1]
存在右侧的 j ,满足 arr[j - 1] > arr[j]
存在一个山峰元素,满足 arr[i] < arr[i + 1] > arr[i + 2] > … > arr[j - 1] > arr[j]
示例:
输入:nums = [1,3,1] 输出:0
输入:nums = [2,1,1,5,6,2,3,1] 输出:3
题目描述给出了我们一个约束条件,要把一个数组变成Mountain Array,那么我们首先要保证它本身数组是符合Mountain Array的定义,那这里我们可以采用双指针的形式满足第一个条件和第二个条件,即左右两指针从数组两端开始并行向中间移动,找到第一个左边小于右边的位置,第一个右边大于左边的位置,那么这时候整个数组被分成两个区间,左右两区间分别都是单调递增的。接下来我们需要找到一个位置分割出左右两区间,满足左区间的最大值小于山峰的那个位置,右区间的最大值大于山峰的那个位置。
下面是Python3的代码实现,具体的解析在代码注释中:
class Solution:
def minimumMountainRemovals(self, nums: List[int]) -> int:
n = len(nums)
# 满足 MountainArray 的数列的长度至少为 3
if n < 3:
return -1
# 构造辅助数组,lis 表示数组 nums 从左到右的最长上升子序列
# lds 表示数组 nums 从右到左的最长上升子序列
lis, lds = [1] * n, [1] * n
for i in range(n):
for j in range(i):
if nums[i] > nums[j]:
lis[i] = max(lis[i], lis[j] + 1)
for i in range(n - 1, -1, -1):
for j in range(i + 1, n):
if nums[i] > nums[j]:
lds[i] = max(lds[i], lds[j] + 1)
res = 0
# 枚举山顶的位置
for i in range(1, n - 1):
# 满足左右两边都有合法的子序列,更新 res 的值
if lis[i] > 1 and lds[i] > 1:
res = max(res, lis[i] + lds[i] - 1)
# 计算需要移除的最小数目
return n - res