O(n)复杂度下求最多元素固定区间最小下界的实现思路咨询
问题诊断
你当前思路存在两个核心问题,既会导致逻辑错误,也无法满足O(n)时间要求:
- 混淆了数值区间长度和索引偏移量:代码中写的
upper_bound[i] = i + L错误把索引偏移当数值范围,L是区间的数值跨度(比如L=3指[下界, 下界+3]的数值范围),不是索引跨3个位置。 - 若按你设想的“给每个元素判断属于哪个候选区间、累加计数”的逻辑实现,必然会出现嵌套循环,时间复杂度为O(n²),不符合要求。
可行的O(n)实现思路(滑动窗口/双指针)
因为输入已经是基数排序后的有序列表,完全不需要嵌套循环,用双指针滑动窗口就能线性处理,两个指针都只单向向前移动,总遍历次数最多为2n,严格符合O(n)复杂度。
核心逻辑
- 维护左指针
l(指向当前候选区间的下界对应元素lst[l])、右指针r(指向当前窗口的最右边界)。 - 对每个左指针位置,右指针持续向后移动,直到遇到第一个满足
lst[r] > lst[l] + L的元素,此时窗口内的元素数量为r - l,也就是以lst[l]为下界的区间能覆盖的元素数。 - 记录最大覆盖元素数,因为左指针是从小到大遍历的,第一次遇到最大计数时的下界就是要求的最小下界,后续遇到同计数的区间直接跳过即可。
对应示例的执行过程(L=3)
输入列表:[1,2,3,4,5,5,6,6,6,12]
- l=0(下界1):右指针走到第一个>1+3=4的位置(索引4,对应值5),覆盖元素数4,暂存最大计数4、最优下界1。
- l=1(下界2):右指针继续走到第一个>2+3=5的位置(索引6,对应值6),覆盖元素数5,更新最大计数5、最优下界2。
- l=2(下界3):右指针继续走到第一个>3+3=6的位置(索引9,对应值12),覆盖元素数7,更新最大计数7、最优下界3。
- 后续l往后移动时,窗口大小只会越来越小,不会超过7,最终返回最优下界3,和预期完全一致。
可直接运行的实现代码
lst = [1,2,3,4,5,5,6,6,6,12] # 已排序 L = 3 n = len(lst) max_count = -1 best_lower = 0 r = 0 for l in range(n): # 右指针持续右移,不回头 while r < n and lst[r] <= lst[l] + L: r += 1 current_count = r - l # 仅当计数更大时更新,同计数保留之前的更小下界 if current_count > max_count: max_count = current_count best_lower = lst[l] print(best_lower) # 输出3
复杂度说明
这里的两层循环看起来有嵌套,但实际右指针r最多从0走到n-1,不会回退,所有循环的总操作次数是O(n),完全符合要求。
内容的提问来源于stack exchange,提问作者ddoo dle
相关产品推荐
相关产品推荐

