当青训营遇上码上掘金 - 寻友之旅 - Python - BFS

77 阅读4分钟

题目

寻友之旅

小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)

请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)

##代码

from collections import deque


def shortest_time(N, K):
    """

    这个程序解决以下问题:

    寻友之旅
    小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
    步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
    公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
    请帮助小青通知小码,小青最快到达时间是多久?
    输入: 两个整数 N 和 K
    输出: 小青到小码家所需的最短时间(以分钟为单位)

    作者:青训营官方账号
    链接:https://juejin.cn/post/7187753682421678137
    来源:稀土掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    """

    # 创建一个双端队列,存储初始状态
    q = deque([(N, 0)])
    # 创建一个集合,存储已经访问过的节点
    visited = set()

    # 当队列不为空时
    while q:
        # 从队列头取出状态
        node, time = q.popleft()
        # 如果当前节点为目标节点,则返回时间
        if node == K:
            return time

        # 如果当前节点没有访问过
        if node not in visited:
            # 将当前节点加入已访问节点集合
            visited.add(node)
            # 将当前节点步行到下一个节点的状态加入队列
            q.append((node - 1, time + 1))
            # 将当前节点步行到下一个节点的状态加入队列
            q.append((node + 1, time + 1))
            # 将当前节点乘坐公交到下一个节点的状态加入队列
            q.append((node * 2, time + 1))
    
    # 如果队列为空,则返回-1
    return -1

if __name__ == '__main__':
    N, K = map(int, "5 17".split())
    print(shortest_time(N, K))

运行结果见寻友之旅 - 码上掘金 (juejin.cn)

总结

这道题属于图论和贪心问题。主要思路是利用广搜算法来搜索从初始节点到目标节点的最短路径。BFS(广度优先搜索)算法,是一种图搜索算法,用于在图中查找最短路径。BFS算法的基本思想是从起始节点开始,沿着图的宽度遍历图中的节点,直到找到目标节点为止。BFS算法可以以最短时间找到最短路径,使用双端队列(deque)存储状态,并且使用一个集合(set)记录访问过的节点,以避免重复访问。

BFS算法可以用于解决很多其他的图搜索问题,例如最少步数问题、最少转换问题、最少时间问题、最少代价问题、最大流量问题、最大匹配问题、最大权重匹配问题、最大连通子图问题、最小生成树问题、最小割集问题和其他图搜索问题。

关于这类题型,一般来说都是求最短路径,可以使用广搜、DFS、BFS等图论算法。这里介绍广搜算法,它是一种用于搜索在图中最短路径的算法。广搜算法从初始状态开始,扩展最近的节点,直到到达终止状态。在这道题中,我们使用了双端队列和集合来存储和跟踪已访问的节点。双端队列是一种特殊的队列,它允许从两端添加和删除元素,这使得BFS算法更加高效。集合是一种无序的数据结构,它可以用来存储唯一的元素,这样就可以避免重复访问节点。

在本题中,小青可以选择步行或公交的方式,步行的速度是每分钟一个节点,公交的速度是每分钟两个节点。为了使小青到达小码的家的最短时间,我们将公交的节点数乘以2,然后进行广搜搜索,寻找最短路径。

总之,BFS算法是一种非常有效的图搜索算法,它可以用来解决很多图搜索问题,而且可以使用双端队列和集合来存储和跟踪已访问的节点,从而提高搜索效率。