LeetCode 热题 HOT 100 第六十四天 279. 完全平方数 中等题 用python3求解

题目地址
给你一个整数 n ,返回和为 n 的完全平方数的最少数量 。
完全平方数是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。

示例 1:
输入:n = 12
输出:3
解释:12 = 4 + 4 + 4

示例 2:
输入:n = 13
输出:2
解释:13 = 4 + 9

提示:
1 <= n <= 10^4
LeetCode 热题 HOT 100 第六十四天 279. 完全平方数 中等题 用python3求解_第1张图片
这题大多数做法是动态规划,但python用动态规划会超时。

解法:广度优先搜索遍历(BFS)
参考:指路
LeetCode 热题 HOT 100 第六十四天 279. 完全平方数 中等题 用python3求解_第2张图片
假设数字n为7,就是下面这个树:

       7
     /   \ 
    6     3
   / \     \
  5   2     2
 / \   \     \
4   1   1     1

结合上面的树和后面的代码来看:
LeetCode 热题 HOT 100 第六十四天 279. 完全平方数 中等题 用python3求解_第3张图片

代码实现:

class Solution:
    def numSquares(self, n: int) -> int:
        #BFS的做法,比较巧妙。每一次是原数字减去了一个平方数,直到出现第一个0,此时走过的层数就是最小数量,即为答案

        #存储在n范围内的完全平方数
        squares = [i*i for i in range(int(n**0.5)+1)] #n=12,squares=[0,1,4,9];n=18,squares=[0,1,4,9,16]

        visited = set() #存储之前出现过的结果,为了剪枝
        queue = [n]
        count = 0 #当前层数
        while queue:
            #这里类似于二叉树的层序遍历
            for _ in range(len(queue)):
                curr = queue.pop(0)
                #当前节点值为0,返回结果
                if curr == 0:
                    return count
                    
                for s in squares:
                    res = curr - s
                    #print('res:',res)
                    if res >= 0 and res not in visited:
                        queue.append(res)
                        visited.add(res) # visited内的元素会自动从小到大排序
                    #print('queue:',queue)
                    #print('visited:',visited)
            count += 1

你可能感兴趣的:(LeetCode,热题,HOT,leetcode,算法,数据结构,力扣,广度优先)