【算法——Python实现】无权图建模通过广度优先遍历解决问题

本文介绍了如何将非图问题抽象成图模型,利用广度优先遍历解决LeetCode 279题——Perfect Squares。通过建立节点与完全平方数之间的边,寻找从正整数n到0的最少完全平方数和,从而找到最短路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有些问题并非图相关问题,但可以通过抽象为图,建立模型,运用广度优先遍历求得一点到另外一点的最短路径,来解决问题

应用:
Leetcode 279. Perfect Squares
给出一个正整数n,寻找最少的完全平方数,使他们的和为n
如 12 = 4+4+4, 13 = 9 + 4

思路:
将从n到0的每个数字作为图中一个点,每两个数字之间如果相差一个完全平方数,则用一条边相连,如:
这里写图片描述
4 3 2 1 0 之间都相差1,1X1 = 1,所以两两之间用一条边相连,而4不仅和3相差1,4更和0相差4,2X2 = 4,所以4和0之间用一条边相连

基于此模型,再通过队列,通过广度优先遍历,这个问题就变成从n到0通过几条路径最短,且一定有解

import Queue
class Solution(object):
    def numSquares(self, n):
        """
        :type n: int
        :rtype: int
        """
        # 广度优先遍历,建模(无权图),每两个数字如果相差一个完全平方数则有一条边,求n到0的最短路径
        if n < 0:
            return None
        q = Queue.Queue()
        q.put((n, 0))  # 第一个数字表示具体第几个数字,第二个数字表示经历了几段路径到达这个数字

        visited = [False for _ in range(0, n)]  # 记录每个数字是否已经被推入过队列
        visited.append(True)
        # 广度优先遍历
        while not q.empty():
            info = q.get()
            num = info[0]
            step = info[1]
            i = 1
            # num - (i*i) >= 0表示还有与num相连的边
            while num - (i*i) >= 0:
                record = num - (i*i)
                if record == 0:
                    return step + 1
                # 防止大量重复数字被推入队列,之前已经推入过队列的数字说明有比当前更短的路径到达此数字,则跳过
                if not visited[record]:
                    q.put((record, step + 1))
                    visited[record] = True
                i += 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值