Python 时间复杂度;查找具有k-唯一字符的最长子字符串“?”;?

Python 时间复杂度;查找具有k-唯一字符的最长子字符串“?”;?,python,string,algorithm,dynamic-programming,Python,String,Algorithm,Dynamic Programming,我正在处理一个叫做“用K个唯一字符找到最长的子字符串”的算法问题。以字符串“aabbccdd”为例。 如果K为1,则最长的子串可以是“aa”。 如果K为2,则最长的子串可以是“aabb”。 如果K为3,则最长的子串可以是“aabbcc” 在这个问题上,你可以使用滑动窗口。使用开始指针和结束指针来表示滑动窗口中的子字符串,如果当前子字符串具有K个或更少的唯一字符,这意味着该字符串可能更长,您只需将结束指针向前移动一个字符 如果向前移动结束指针后,当前子字符串超过K个唯一字符,则表示前一个子字符串是

我正在处理一个叫做“用K个唯一字符找到最长的子字符串”的算法问题。以字符串“aabbccdd”为例。 如果K为1,则最长的子串可以是“aa”。 如果K为2,则最长的子串可以是“aabb”。 如果K为3,则最长的子串可以是“aabbcc”

在这个问题上,你可以使用滑动窗口。使用开始指针和结束指针来表示滑动窗口中的子字符串,如果当前子字符串具有K个或更少的唯一字符,这意味着该字符串可能更长,您只需将结束指针向前移动一个字符

如果向前移动结束指针后,当前子字符串超过K个唯一字符,则表示前一个子字符串是具有K个唯一字符的潜在候选字符串。在这种情况下,只需向前移动开始指针,直到当前子字符串具有K个或更少的唯一字符

我不明白为什么这个问题的时间复杂性是线性的。从表面上看,它似乎是二次的。我们有两个指针。指针i可能是一个线性扫描。通过线性扫描,j保持固定。所以我觉得这是二次的


TLDR:有人能为我清楚地推断出线性时间复杂度吗?这对我来说并不明显。我喜欢滑动窗口的概念,它隐式地迭代N^2个子字符串。然后利用问题的属性设置起点和终点,尝试使其线性化。但我看不出这是线性的。这在我的分析中看起来是二次的

为了处理时间复杂度问题,它总是有助于扩大问题的规模,并考虑大规模的案例

如果您的字符串有数千个字符长,我们仍然只有一个开始指针和一个结束指针。关键是两个指针只能向前移动(沿着字符串)。因此,这一过程的复杂性肯定是
O(n)
,因为它们只在字符串中一起向前移动-因此这一过程所需的时间与字符串的长度(到达末尾所需的时间)成正比


如果我们要检查从开始指针到字符串末尾的所有窗口的结束指针,然后增加开始指针并再次检查所有这些子字符串(从开始指针到字符串末尾),则时间复杂度将达到
O(n^2)
。在这里,我们看到,当我们使用开始指针(
O(n)
)在字符串上迭代时,每个迭代都涉及到它自己的嵌套迭代,即将结束指针移动到字符串的末尾。这将使复杂性
O(n^2)

然而,如前所述,两个指针只向前移动,因此最多是
O(n)
复杂度。

算法为
O(n)
意味着操作数最终由某个线性函数
a*n
限定,其中
a
是常数

对于依赖列表遍历的算法,这并不意味着它们必须只遍历列表一次。这意味着他们最多必须遍历列表
a
次,并且
a
不取决于列表长度

在您的例子中,您有两个指针,但每个指针只遍历列表一次。这意味着您总是只遍历列表两次

还有一点值得注意的是,虽然n字符串中的子字符串数量增加了
O(n^2)
,但您并没有遍历所有子字符串。实际上,只有多达
n
个指针是有效的,并且这些指针是您使用两个指针遍历进行检查的唯一指针


通过字符串
'abcdef'
k=3
中的示例,您不必检查子字符串
'abcd'

谢谢--我非常感谢您的详细回答。这让我卡住了一段时间。@asndonsadoasndo231213没问题,O符号经常让人困惑!如果这为你澄清了问题,请接受:)我理解他们都在前进——这是有道理的。在某些情况下,开始指针并不总是随着结束指针向前移动(据我所知)。如果当前候选字符串(由起始和结束指针限定)的唯一字符比它应有的多,我们将递增起始指针。我在想这个“递增过程”的一些界限。这个“递增过程”可能是
O(N)
,这就是为什么争论这是一个
O(N^2)
时间。好的,另一种思考它的方式是,在遍历整个字符串之后,结束指针递增了多少次<代码>n
时间对吗?开始指针增加了多少次<代码>n时间对吗?因此,算法必须是
O(n)
。任何一个指针在字符串中都不会向后移动,即使结束指针可能停止递增,开始指针也会递增,但它们仍然只会向前移动到字符串的结尾。嗯,很有趣。是的,这很有道理。它的计算结果可能大致是2N。