1. 题目解析与核心思路
这道题来自LeetCode第486场周赛的第一题,题目编号100971。题目要求我们找到一个数组中最小的前缀移除次数,使得剩余数组严格递增。所谓"严格递增",指的是数组中每个元素都必须严格大于前一个元素(即不能有相等或递减的情况)。
理解题意时,我们需要抓住几个关键点:
- 移除的是"前缀":这意味着我们只能从数组开头连续移除元素,不能跳过中间元素
- 严格递增:相邻元素不能相等,必须保持递增关系
- 最小移除次数:我们需要找到最优解
举个例子,对于数组[1,2,3,1,2]:
- 初始序列[1,2,3]是严格递增的
- 遇到第二个1时破坏了递增性,此时需要移除前面所有元素(即移除[1,2,3])
- 然后从新的1开始,[1,2]又是严格递增的
- 所以总共需要移除3个元素
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算法设计与实现思路
2.1 暴力解法分析
最直观的解法可能是暴力枚举所有可能的前缀移除方案,然后检查剩余数组是否严格递增。但这种解法的时间复杂度会达到O(n²),对于较大的数组显然不够高效。
2.2 优化思路
通过观察可以发现,一旦遇到破坏严格递增的元素,前面所有的元素都必须移除。这给了我们一个重要的启示:可以一次遍历数组,在遇到"下坡"或"平坡"时,计算需要移除的元素数量。
具体来说:
- 维护两个指针:left和right
- left记录当前有效序列的起始位置前一个位置(初始为-1)
- right从1开始遍历数组
- 当发现nums[right] <= nums[right-1]时:
- 计算需要移除的元素数量:right-1 - left
- 更新left为right-1
- 最后返回累计的移除数量
这种解法只需要一次遍历,时间复杂度为O(n),空间复杂度为O(1),非常高效。
3. 代码实现与详细解析
3.1 Java实现代码
java复制class Solution {
public int minimumPrefixLength(int[] nums) {
int left = -1, ret = 0, n = nums.length;
for(int right = 1; right < n; right++
