文巾解题 LCP 07. 传递信息

Posted 刘文巾

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文巾解题 LCP 07. 传递信息相关的知识,希望对你有一定的参考价值。

1 题目描述

2 解题思路

2.1 动态规划

定义动态规划的状态 dp[i][j] 为经过 i 轮传递到编号 j 的玩家的方案数,其中0≤i≤k,0≤j<n。

由于从编号 0 的玩家开始传递,当i=0 时(第0轮),一定位于编号 0 的玩家,不会传递到其他玩家,因此动态规划的边界情况如下:

对于传信息的关系 [src,dst],如果第 i 轮传递到编号 src 的玩家,则第i+1 轮可以从编号 src 的玩家传递到编号dst 的玩家。因此在计算dp[i+1][dst] 时,需要考虑可以传递到编号dst 的所有玩家。

由此可以得到动态规划的状态转移方程,其中0≤i<k:

最终得到dp[k][n−1] 即为总的方案数。

class Solution:
    def numWays(self, n: int, relation: List[List[int]], k: int) -> int:
        dp = [[0] * n for _ in range(k + 1)]
#每一轮,从0点出来可以有几条不同的线路到某一个点

        dp[0][0] = 1
#第0轮(初始情况)只有0点可以到达

        for i in range(k):
            for edge in relation:
                src = edge[0]
                dst = edge[1]
                dp[i + 1][dst] += dp[i][src]
#每一轮的情况由上一轮决定
        return dp[k][n - 1]

上述实现的空间复杂度是 O(kn)。进一步分析可以知道,dp[i][] 的值只和 dp[i−1][] 的值有关。

因此可以将二维数组变成一维数组,将空间复杂度优化到 O(n)。

class Solution:
    def numWays(self, n: int, relation: List[List[int]], k: int) -> int:
        dp = [0] * n
        dp[0] = 1
        for i in range(k):
            tmp=[0] * n
            for edge in relation:
                
                src = edge[0]
                dst = edge[1]
                tmp[dst] += dp[src]

            dp=tmp
        return dp[n - 1]

2.2 深度优先搜索

class Solution:
    def numWays(self, n: int, relation: List[List[int]], k: int) -> int:
        dit={}
        for i in relation:
            if i[0] in dit:
                dit[i[0]].append(i[1])
            else:
                dit[i[0]]=[i[1]]
        for i in range(n):
            if i not in dit:
                dit[i]=[]
#字典,字典的key为每一个点,value为每一个点可以连接到的点

        count=0
#经过k轮可以到达n-1的路线数

        def func(node,k_remain):
#node表示目前从那个点出发
#k_remain表示还剩几条边可以连

            nonlocal count
            if(k_remain==0 and node==n-1):
                count+=1
#如果还有0条边可以连,而且目前到达了n-1点,那么经过k轮可以到达n-1的路线数加一
            elif(k_remain==0):
                pass
#否则,就是到了别的点,那么不会有任何情况
            else:
                for i in dit[node]:
                    func(i,k_remain-1)
#走到node的邻居那儿去,剩余的边数减一
        func(0,k)
        return(count)

2.3 广度优先遍历

class Solution:
    def numWays(self, n: int, relation: List[List[int]], k: int) -> int:
        dit={}
        for i in relation:
            if i[0] in dit:
                dit[i[0]].append(i[1])
            else:
                dit[i[0]]=[i[1]]
        for i in range(n):
            if i not in dit:
                dit[i]=[]
#和2.2一样,建立一个字典

        queue=[0]
#建立一个队列,表示经过time轮目前可以到达的点(可以有重复)
        time=0
#目前已经走了几条边(走了几轮)

        while(time<k):
            tmp_size=len(queue)
#当前轮有几个点,一会把他们一个一个弹出队列
            for _ in range(tmp_size):
                x=queue.pop(0)
                queue.extend(dit[x])
#当前轮的点的邻居入队列
            time+=1

        return(queue.count(n-1))
#最后就是经过k轮之后,一共可以到达的点。里面有几个n-1,就说明有几条路线到n-1

以上是关于文巾解题 LCP 07. 传递信息的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode LCP 07. 传递信息

LeetCode LCP 07. 传递信息

leetcode LCP.07 传递信息

leetcode LCP.07 传递信息

leetcode LCP 07. 传递信息

LeetCode LCP 07. 传递信息 / NC111 最大数 / NC16 判断二叉树是否对称 / NC13 二叉树的最大深度