连续子数组问题的O(n)解法验证及最优复杂度问询
通配子数组问题:时间复杂度分析与验证
嘿,咱们来一步步拆解你的问题,先给你吃个定心丸——你的解法确实是O(n)线性时间复杂度,然后再聊聊怎么从问题本身判断最优时间复杂度。
一、你的代码为什么是O(n)?
先看你的代码逻辑:
forwardCounter从左到右把数组每个元素扫了恰好一次,没有回头;- 只有碰到通配数
k的时候,才会启动backwardCounter往前找小于k的元素,但这里有个关键:每个元素只会被backwardCounter访问最多一次。
举个直观的例子:假设数组是[x,y,z,k,a,b,k],第一个k触发回溯检查z,y,x,第二个k只会检查b,a,绝不会再碰z,y,x。所有元素的总访问次数加起来就是n(forward遍历)加上最多n次(backward遍历),总和还是线性的,所以时间复杂度是O(n)。
二、怎么从问题本身判断最优时间复杂度?
判断一个问题的最优时间复杂度,核心是看「必须做的最小工作量」和「能达到的最快速度」:
1. 先确定下界:至少要O(n)时间
这个问题里,我们没办法跳过任何一个元素:
- 每个元素要么是通配数
k,得统计以它结尾的所有合法子数组; - 要么是
k前面的元素,得判断它能不能算进某个合法子数组里。
也就是说,所有元素都必须被检查至少一次,所以问题的时间复杂度下界是Ω(n)(线性时间是底线,不可能更快了)。
2. 再看是否能达到线性时间
既然你已经写出了O(n)的解法,而且我们知道底线是Ω(n),那这个问题的最优时间复杂度就是O(n)——没有比这更快的解法了。
三、结合示例验证你的代码
针对你给的示例数组{4,5,6,4,3,2,4,8,2,4},通配数k=4:
- 第一个
4(索引0):直接计数+1,总长度=1; - 第二个
4(索引3):计数+1(总长度=2),前置的6不小于4,直接停止回溯; - 第三个
4(索引6):计数+1(总长度=3),回溯到2(+1→4)、3(+1→5),碰到4就停; - 第四个
4(索引9):计数+1(总长度=6),回溯到2(+1→7),碰到8就停;
最终输出7,完全符合预期。
内容的提问来源于stack exchange,提问作者Bala Ji
相关产品推荐
相关产品推荐

