【问题标题】:Time complexity for a solution to the heater problem on Leetcode在 Leetcode 上解决加热器问题的时间复杂度
【发布时间】:2021-03-30 13:15:23
【问题描述】:

从 Leetcode 上的一个热门问题中考虑这个 python 解决方案:

 def findOptimalRadius(houses, heaters):
        houses.sort()
        heaters.sort()
        last = len(heaters) - 1
        x1,x2 = 0,0
        res = 0
        for house in houses:
            while x2 < last and house > heaters[x2]:
                x1, x2 = x2, x2+1
            dist1,dist2 = abs(heaters[x1] - house), abs(heaters[x2] - house)
            res = max(res, min(dist1,dist2))
        return res

(给定 N 个房屋和 M 个加热器)

显然,如果我们在开始时对两个数组进行排序,则空间复杂度被认为是 O(N log N + M log M),如果它们已经排序,则空间复杂度被认为是 O(N+M)。

但我不明白为什么 for 循环和嵌套的 while 循环只占 O(N+M)。

不应该是 O(N*M),因为它们是嵌套的,而且在最坏的情况下,while 循环会遍历所有加热器?

感谢您帮助我了解在这种情况下如何计算时间复杂度

【问题讨论】:

  • 你能解释一下这个问题,这也是一个解决方案吗?
  • 我不确定是否可以在此处添加链接,但您可以在谷歌上输入“leetcode 加热器问题”轻松找到问题描述

标签: python while-loop time-complexity big-o


【解决方案1】:

这是 O(N+M),因为第二个循环对每个元素只运行一次。如果你注意到,x2 永远不会减少,它总是从最后一个状态继续并增加 1,所以当它达到值时,最后一个循环永远结束。因此,不是每次都通过阵列加热器中的每个元素,而是只通过一次,当它到达终点时,即使阵列房屋中仍有元素,while循环也不会启动。

至于你的直觉。如果对于阵列房屋中的每个元素,您将遍历每个加热器,那将是正确的,但事实并非如此。

请注意,嵌套循环并不意味着时间复杂度是 O(N*M)(在这种情况下)或 O(N^x)(x 是嵌套循环的数量)。您必须分析每个单独的循环在做什么。

编辑: 评论如下图:

N=20
M=15

i= current for loop element 
j= current while loop element

i=1 -> j = 1 , 2 , 3 , 4
i=2 -> j = 4 , 5
i=3 -> j = 5 , 6 , 7 , 8 
i=4 -> j = 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15
i=5 -> j = 15 (while loop is at its end so it won't be initiated)
i=6 -> j = 15 
 .
 .
 .
i=20 -> j = 15 

您可以注意到,当到达阵列加热器的末端时,while 循环将结束并且永远不会再次启动。所以while循环的复杂度是O(M),for循环的复杂度是O(N)。由于不是为每个 i 重新启动 while 循环,而是从最后一个状态继续,所以总复杂度是 O(N+M) 而不是 O(N*M)。

试想一下,您只通过一次加热器中的每个元素,对于房屋也是如此(您永远不会重新访问某些元素)。

如果您为每所房子重新检查整个加热器阵列,那么复杂性确实是 O(N*M)。

【讨论】:

  • 正如你所提到的,x2 总是继续增加,直到它达到最后的值。但最后的值代表加热器的数量。因此,在最坏的情况下,它会在遍历所有房屋的循环中遍历所有加热器,对吗?
  • 是的,在最坏的情况下,它会遍历所有加热器,但由于 while 循环在遍历所有加热器时不会重新启动,因此 for 循环中的每次后续传递都将忽略while 循环。因此,例如,如果 for 循环位于房屋数组的第一个元素上,而 while 循环遍历所有加热器并到达最后一个元素,则当 for 循环传递到下一个房屋时,而循环将在其末尾,所以它只会从 x2==last 开始被跳过。即使 while 循环是嵌套的,它也并不真正依赖于 for 循环。
  • 非常感谢您的精彩解释,现在我明白了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-21
  • 1970-01-01
  • 2022-01-12
  • 2020-11-13
相关资源
最近更新 更多