我正在使用名为“查找带有K个唯一字符的最长子字符串”的算法问题。以字符串“aabbccdd”为例。 如果K为1,则最长的子串可以是“aa”。 如果K是2,则最长的子串可以是“aabb”。 如果K为3,则最长的子串可以是“aabbcc”。
这个问题,你可以利用滑动窗口。使用开始指针和结束指针来表示滑动窗口中的子字符串,如果当前子字符串具有K个唯一字符或更少,则表示该字符串可能更长,您只需要将结束指针向前移动一个字符。
如果在向前移动结束指针后当前子字符串超过K个唯一字符,则表示前一个子字符串是具有K个唯一字符的潜在候选字符。在这种情况下,您只需要向前移动开始指针,直到当前子字符串具有K个或更少的唯一字符。
我不明白为什么时间复杂度是线性的。从表面看,它似乎是二次的。我们有两个指针。指针我可能是一个线性扫描。 j通过线性扫描保持固定。所以这对我来说似乎是二次方的。
TLDR:有人可以清楚地推断出我的线性时间复杂度吗?这对我来说并不明显。我喜欢滑动窗口的概念,隐含地遍历N ^ 2个子串。然后利用问题的属性来设置起点和终点,以尝试使其成为线性。但我不知道这是如何线性的。这在我的分析中看起来是二次的
答案 0 :(得分:2)
为了解决时间复杂性问题,总是有助于扩大问题并考虑大量案例。
如果您的字符串长达数千个字符,我们仍然只有一个开始指针和一个结束指针。关键是两个指针只会向前移动(沿着字符串)。因此,这种复杂性肯定是O(n)
,因为它们只是通过字符串一起向前移动 - 所以这个过程所花费的时间与字符串的长度(到达结尾所需的时间)成正比
如果我们要检查从开始指针到字符串结尾的结束指针的所有窗口,然后再增加开始指针并再次检查所有这些子字符串,则会出现O(n^2)
的时间复杂度(从开始指针到字符串的结尾)。在这里,我们看到当我们使用开始指针(O(n)
)迭代字符串时,每次迭代都涉及自己的嵌套迭代,将结束指针移动到字符串的末尾。这会使复杂性O(n^2)
。
然而,如前所述,您的指针只会前进,所以最多只有O(n)
复杂度。
答案 1 :(得分:2)
算法为O(n)
意味着操作数最终受某些线性函数a * n
的限制,其中a
是常量。
对于依赖于列表遍历的算法,并不意味着它们必须只遍历列表一次。这意味着他们必须最多a
次遍历列表,并且a
不依赖于列表长度。
在你的情况下,你有两个指针,但它们每个只遍历列表一次。这意味着您始终只遍历列表两次。
还有一点需要注意的是,虽然n字符串中的子字符串数量增长O(n^2)
,但您并没有遍历所有子字符串。事实上,只有n
只有它们是有效的,而这些是你用双指针遍历检查的唯一的。
例如,在带有'abcdef'
的字符串k = 3
中,您不会检查子字符串'abcd'
。