题目链接:Leetcode 1671. 得到山形数组的最少删除次数
题意:
我们定义 arr
是 山形数组 当且仅当它满足:
arr.length >= 3
- 存在某个下标
i
(从 0 开始) 满足0 < i < arr.length - 1
且:arr[0] < arr[1] < ... < arr[i - 1] < arr[i]
arr[i] > arr[i + 1] > ... > arr[arr.length - 1]
给你整数数组 nums
,请你返回将 nums
变成 山形状数组 的 最少 删除次数。
解题思路:
如果只看左边或者右边,那么这就是一个典型的最长上升子序列, 两边同时看就是从两边开始的最长上升子序列
最终结果只需把中间的最大值的减去一次即可
class Solution {
public:
int minimumMountainRemovals(vector<int>& nums) {
int ans = 0, dp[1005], dp1[1005];
int n = nums.size();
memset(dp, 0, sizeof(dp));
for (int i = 0; i < n; i++) {
dp[i] = 1;
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
}
for (int i = 0; i < n; i++) {
cout << dp[i] << endl;
}
for (int i = n - 1; i >= 0; i--) {
dp1[i] = 1;
for (int j = n - 1; j > i; j--) {
if (nums[j] < nums[i]) {
dp1[i] = max(dp1[i], dp1[j] + 1);
}
}
}
for (int i = 0; i < n; i++) {
if (dp[i] > 1 && dp1[i] > 1) {
ans = max(ans, dp[i] + dp1[i] - 1);
}
}
return n - ans;
}
};