BFS解决方案查找最不完美的正方形

时间:2019-04-15 08:59:36

标签: python

我正在研究Perfect Squares - LeetCode

  
      
  1. 完美正方形
  2.   
     

给定一个正整数 n ,找到求和为 n 的最小平方数(例如1, 4, 9, 16, ...)。

     

示例1:

Input: n = 12
Output: 3 
Explanation: 12 = 4 + 4 + 4.
     

示例2:

Input: n = 13
Output: 2
Explanation: 13 = 4 + 9.

关键思想将其转换为图中n到0的最短查找路径

enter image description here

标准DFS解决方案

class Solution:
    def numSquares(self, n):
        """
        :type n: int
        :rtype: int
        """
        from collections import deque 
        #declare
        queue = deque()
        visited = set()
        #intitiate 
        step = -1
        queue.append(n)
        visited.add(n)

        while queue:
            step += 1
            size = len(queue)  

            for _ in range(size):
                cur = queue.popleft()
                if cur == 0: return step  #terminating checking 

                #strech to collect next nodes 
                i = 1
                next_ = cur - i**2 #
                while next_ >= 0:
                    if next_ not in visited:
                        queue.append(next_)
                        visited.add(next_)

                    i += 1
                    next_  = cur - i**2
  

运行时间:2532毫秒,比Perfect Squares的Python3在线提交的40.71%快。   内存使用量:14 MB,不到Perfect Squares在线提交的Python3的18.25%。

收集下一个节点的部分不是很简洁

                #strech to collect next nodes 
                i = 1
                next_ = cur - i**2 #
                while next_ >= 0:
                    if next_ not in visited:
                        queue.append(next_)
                        visited.add(next_)

                    i += 1
                    next_  = cur - i**2

试图将其修改为

            i = 1                  
            while  cur - i** 2 >= 0:
                next_ = cur - i ** 2:
                if next_ not in visited:
                    queue.append(next_)
                    visited.add(next_)
                i += 1

它可以工作,但超过了时间限制。

如何重构该部分?

1 个答案:

答案 0 :(得分:1)

我认为TLE的原因是您两次进行了cur - i** 2,在这里square很麻烦。我更改为cur - i * i,通过。

在大多数情况下,加倍计算不会导致TLE,但是这里的DFS足够慢(在我的测试中花费2560ms),所以它很在意。

如果您不想两次分配next_,并且python比较时不支持语法分配,如下所示:

while (next_ = cur - i**2) >= 0:

所以您可以尝试一下(我认为这也很丑):

i = 1
while True:
    next_ = cur - i ** 2
    if next_ < 0:
        break

    if next_ not in visited:
        queue.append(next_)
        visited.add(next_)
    i += 1

顺便说一句,我只是注意到它与BFS无关,而BFS是解决此问题的更快解决方案。