【问题标题】:Time Complexity for LeetCode 3. Longest Substring Without Repeating CharactersLeetCode 3. 不重复字符的最长子串的时间复杂度
【发布时间】:2021-12-26 01:40:48
【问题描述】:

问题:给定一个字符串s,求最长子串的长度 没有重复的字符。

示例:输入:s = "abcabcbb" 输出:3 解释:答案是 "abc",长度为3。

我的解决方案:

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        seen = set()
        l = r = curr_len = max_len = 0
        n = len(s)
        
        while l < n:
            if r < n and s[r] not in seen:
                seen.add(s[r])
                curr_len += 1
                max_len = max(curr_len, max_len)
                r += 1
            else:
                l += 1
                r = l
                curr_len = 0
                seen.clear()
                
        return max_len

我知道这不是一个有效的解决方案,但我无法弄清楚它的时间复杂度。

我访问了字符串中的每个字符,但是对于每个字符,窗口都会扩展,直到找到一个重复的字符。所以每个 char 最终都会被访问多次,但不确定是否有足够的时间来证明 O(n2) 时间复杂度是合理的,而且显然它比 O(n) 更糟糕。

【问题讨论】:

  • 欢迎来到Stack Overflow. 请注意这不是代码编写或辅导服务。我们可以帮助解决具体的技术问题,而不是关于软件理论或建议的开放式请求。
  • 这不是开放式的。这是一个有特定解决方案的特定问题。

标签: python algorithm time-complexity


【解决方案1】:

如果您知道可以组成输入的字符集的大小,您可以声称该算法为 O(n),因为您的窗口可以扩展的长度受到您之前可以传递的不同字符数量的限制遇到重复,这取决于您正在使用的字符集的大小,它本身是一些与字符串长度无关的常数。例如,如果您只使用小写字母字符,则算法为 O(26n) = O(n)。

更准确地说,你可以说它在 O(n*(min(m,n)) 中运行,其中 n 是字符串的长度,m 是字符串字母表中的字符数。原因最重要的是,即使您以某种方式使用无限唯一字符的字母表,最坏的情况是您正在对字符串末尾执行双 for 循环。然而,这意味着如果您可以遇到的可能字符数在字符串超过字符串的长度时,您的 O(n^2) 性能最差(当字符串的每个字符都是唯一的时会发生这种情况)。

【讨论】:

  • 这是真的!对于较大的 n,每次迭代都将被限制在 26,直到我达到迭代 n-26 并向前,对于它,它将被限制在小于 26,因为无论如何它都会在 26 之前到达字符串的末尾。但是是的,对于较大的 n,它将是 O(26n)。 跟进:如果我提供一个提前终止条件,说明如果在任何给定的迭代中我到达字符串的末尾,算法就会完成,因为那将是最大长度。时间复杂度是多少?
  • 答案:我相信对于大的 n,它仍然是 O(26n),因为提前终止只有在我进入迭代 n-26 并向前时才有用。唯一的 O(n^2) 是如果字符串的所有字符都是唯一的,对于大 n 它不会发生,除非我以某种方式使用神奇的无限字母表
  • 是的,我在考虑具有成千上万个字符的中文或 Unicode 字符集,其中最坏的情况 n^2 行为更实际可实现,但你是对的,除了神奇的字母表 m最多仍然是一些大常数,并且它是渐近 O(n)。
  • 我同意这种提前终止检查可能不会改变事情,因为你说的是​​较小的字母,因为对于 n
  • 因为在评估算法的复杂性时,您放弃了所有常量 O(26n) = O(n)
猜你喜欢
  • 2017-06-20
  • 2018-10-18
  • 2020-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多