You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

数组删除比左侧小元素的操作次数求解及代码优化

问题分析

你当前需要实现的是重复删除数组中所有比左侧相邻元素小的元素,统计总操作轮次,现有暴力模拟的实现存在性能瓶颈。

现有代码的不足

你现有的实现是逐轮模拟删除过程,最坏时间复杂度为O(n²):比如输入严格递减的数组时,需要执行n-1轮操作,每轮都要遍历当前剩余的所有元素,当数组长度较大时运行效率会非常低。

优化思路:单调栈O(n)实现

我们可以通过一次遍历+单调栈的方式直接计算出每个元素被删除的轮次,所有元素删除轮次的最大值就是我们要求的总操作次数:

  • 栈中存储(元素值, 该元素被删除的轮次)对,维护栈内元素值单调不下降
  • 对于每个新元素,弹出栈中所有比当前元素小的元素,记录弹出的元素中最大的删除轮次max_del
  • 如果弹出后栈不为空,说明当前元素会被栈顶的更大元素删除:
    • 如果弹出过元素,当前元素的删除轮次是max_del + 1
    • 如果没弹出过元素,当前元素的删除轮次是1
  • 如果弹出后栈为空,说明当前元素是左侧最大的,不会被删除,删除轮次记为0
  • 全局维护所有删除轮次的最大值,就是最终答案
优化后代码
#include <stack>
#include <algorithm>
using namespace std;

int numberOfTimes(int array[], int n) {
    if (n <= 1) return 0;
    stack<pair<int, int>> st;
    int res = 0;
    for (int i = 0; i < n; i++) {
        int cur_del = 0;
        // 弹出栈中比当前元素小的元素
        while (!st.empty() && st.top().first < array[i]) {
            cur_del = max(cur_del, st.top().second);
            st.pop();
        }
        // 栈不为空,当前元素会被删除
        if (!st.empty()) {
            cur_del += 1;
            res = max(res, cur_del);
        }
        // 入栈
        st.push({array[i], cur_del});
    }
    return res;
}
复杂度说明
  • 时间复杂度:O(n),每个元素只会入栈和出栈各一次
  • 空间复杂度:O(n),最坏情况栈中需要存储所有元素(比如严格递增的数组)
测试验证

输入你给出的测试用例[10, 9, 7, 8, 6, 5, 3, 4, 2, 1],上述代码返回结果为2,和预期一致。

内容的提问来源于stack exchange,提问作者asd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 22:54:04