列表迭代优化:寻找满足条件的最长子段算法优化需求
优化最长符合条件连续子段查找算法
问题描述
实现函数从给定列表t中找出满足以下条件的最长连续子段:
- 子段最后一个元素 ≥ 第一个元素;
- 子段最后一个元素与第一个元素的差值 ≤ 给定整数
x。
算法需支持长度达105、元素为1≤数值≤109的随机整数列表。
原代码性能瓶颈
原使用嵌套for循环的实现时间复杂度为O(n²),对于n=1e5的输入完全无法在合理时间内运行,必须优化到线性或线性对数时间复杂度。
原代码:
def find(t: list, x: int): n = len(t) max_len = 0 for i in range(n): for j in range(i, n): if t[j] >= t[i] and t[j] - t[i] <= x: max_len = max(max_len, j - i + 1) return max_len if __name__ == "__main__": print(find([1, 4, 6], 1)) # 1 print(find([1, 4, 6], 10)) # 3 print(find([4, 1, 10, 5, 14], 1)) # 4 print(find([4, 1, 10, 5, 14], 10)) # 5 print(find([9, 8, 7, 6, 5, 4, 3, 2, 1], 100)) # 1
优化方案:单调队列
利用单调递增队列维护可能的子段起点索引,每个元素仅入队和出队一次,时间复杂度降至O(n)。
核心逻辑:
- 维护一个双端队列,队列中保存的索引对应的
t值严格单调递增; - 遍历每个位置
j:- 从队列头部移除所有不满足
t[j]-t[i] ≤x的索引i(后续更大的j只会让差值更大,这些i不可能再成为有效起点); - 此时队列头部的
i是能与j形成最长符合条件子段的起点,计算长度并更新最大长度; - 从队列尾部移除所有
t[k] ≥ t[j]的索引k(对于未来的j',j作为起点更优:t[j]更小,更容易满足差值条件,且位置更靠后,子段长度可能更长); - 将
j加入队列尾部。
- 从队列头部移除所有不满足
优化后的代码
from collections import deque def find(t: list, x: int): n = len(t) max_len = 0 q = deque() for j in range(n): # 移除头部不满足差值限制的索引 while q and t[j] - t[q[0]] > x: q.popleft() # 计算当前j对应的最长子段长度 current_len = j - q[0] + 1 if q else 1 if current_len > max_len: max_len = current_len # 维护队列的单调递增性 while q and t[q[-1]] >= t[j]: q.pop() q.append(j) return max_len if __name__ == "__main__": print(find([1, 4, 6], 1)) # 1 print(find([1, 4, 6], 10)) # 3 print(find([4, 1, 10, 5, 14], 1)) # 4 print(find([4, 1, 10, 5, 14], 10)) # 5 print(find([9, 8, 7, 6, 5, 4, 3, 2, 1], 100)) # 1
验证结果
所有测试用例均与原代码输出一致,且能高效处理1e5级别的输入。
内容的提问来源于stack exchange,提问作者user16834984
相关产品推荐
相关产品推荐

