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

如何在O(N)时间复杂度下查找数组每个元素右侧大于等于自身的最右索引

结论

针对无特殊约束的通用整数数组场景,不存在O(N)时间复杂度的解法,目前可实现的最优时间复杂度为O(NlogN),即你已经实现的单调栈配合二分查找的方案。

无法达到O(N)的原因

单调栈确实能解决很多数组区间最值类问题,且这类可实现O(N)复杂度的问题,本质上都可以通过单调栈的单次栈顶比较直接得到答案,无需额外查找,比如「下一个更大元素」类问题只需要找最近的符合条件的元素,栈顶元素直接就是结果。
但本问题要求的是最右侧的符合条件的元素,该特性决定了无法仅通过栈顶单次比较得到结果,必须对栈中维护的有序候选序列做查找操作,而有序序列的查找最低时间复杂度为O(logN),叠加N次遍历后整体复杂度为O(NlogN)。

现有O(NlogN)解法原理

你给出的实现逻辑正确,核心思路如下:

  • 倒序遍历数组,维护一个严格单调递减的栈,栈中存储索引,索引对应的元素值严格递减
  • 倒序遍历时,只有当前元素比栈顶索引对应的元素更大时才入栈,保证栈中元素越靠栈顶索引越靠左、对应值越小,整个栈的元素值保持严格单调递减
  • 对每个遍历到的元素nums[i],栈中存储的都是i右侧的候选索引,由于栈值单调递减,可通过二分查找直接找到第一个大于等于nums[i]的元素对应的索引,也就是最右侧的符合要求的j

对应的Python实现如下:

import bisect

def rightmostGreaterOrEqual(nums):
    A, n = nums, len(nums)    
    indx = [-1]*n 
    stack, stackv = [], []
    for i in range(n-1, -1, -1):
        if not stack or nums[stack[-1]] < nums[i]:
            stack.append(i) 
            stackv.append(nums[i])
        else:
            idx = bisect.bisect_left(stackv, nums[i])
            indx[i] = stack[idx]
    return indx

# 测试用例
B = [9,8,1,0,1,9,4,0,4,1]
rightGreat = rightmostGreaterOrEqual(B)
print(B)
# 输出: [9, 8, 1, 0, 1, 9, 4, 0, 4, 1]
print(rightGreat)
# 输出: [5, 5, 9, 9, 9, -1, 8, 9, -1, -1]
特殊场景优化

如果你的输入数组存在特殊约束,比如元素取值范围很小(例如限定在1~100区间),可以用后缀最大值计数的方式实现O(N + K)的时间复杂度,其中K为元素取值范围大小,但该方案仅适用于特定场景,不具备通用性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 03:27:04