【leetcode】1671. Minimum Number of Removals to Make Mountain Array
题目如下:
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) with0 < 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 makenums
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
.
解题思路:动态规划。先假设dp_left[i] = v 表示第i个元素为最高点的时候,左半部分需要删除的元素数量的最小值。如果前一个保留的元素下标为j,那么表示需要删除掉(i-j+1)个元素,同时可以得到状态转移方程: dp[i] = max(dp[j] + (i-j+1)) (j <= i)。右半部分也同理,最需要求出左半部分和右半部分和最小的i即可。
代码如下:
class Solution(object): def minimumMountainRemovals(self, nums): """ :type nums: List[int] :rtype: int """ dp_left = range(len(nums)) for i in range(1,len(dp_left)): for j in range(i): if nums[i] > nums[j]: dp_left[i] = min(dp_left[i],dp_left[j] + (i-j-1)) dp_right = range(len(nums)-1,-1,-1) for i in range(len(dp_right)-2,-1,-1): for j in range(len(dp_right)-1,i,-1): if nums[i] > nums[j]: dp_right[i] = min(dp_right[i], dp_right[j] + (j - i - 1)) res = len(nums) - 3 for i in range(1,len(dp_left)-1): if dp_left[i] != i and dp_right[i] != (len(dp_right) - i - 1): res = min(res,dp_left[i] + dp_right[i]) return res