力扣 LCP 07. 传递信息

题目来源:https://leetcode-cn.com/problems/chuan-di-xin-xi/

大致题意,有n个点(从0到n-1),然后有若干个消息(可视为节点之间的有向边),判断从0点经过k步到n-1点的路径有几条。中间可以有重复边。

简单思路:

使用dfs。首先根据有向边形成每个点的出边列表,然后通过dfs走k步,判断当前点是否为n-1,若为,则有效路径+1。

public class ParseMsgDFS {
    int ways, n, k;
    List<List<Integer>> edges;

    public int numWays(int n, int[][] relation, int k) {
        ways = 0; // 初始化
        this.n = n;
        this.k = k;
        edges = new ArrayList<List<Integer>>(); 
        for (int i = 0; i < n; i++) { // 初始化
            edges.add(new ArrayList<Integer>());
        }

        for (int[] edge : relation) { // 获取出边列表
            int src = edge[0];
            int des = edge[1];
            edges.get(src).add(des);
        }

        dfs(0, 0);

        return ways;
    }

    public void dfs(int index, int steps) {
        if (steps == k) {
            if (index == n-1) // k步到达n-1
                ways++;
            return;
        }

        List<Integer> des = edges.get(index);
        for (int next : des) {
            dfs(next, steps+1);
        }
    }
}

这个方法消耗比较大。

动态规划

使用dp[i][j]表示第i步到达节点j的路径数。
那么可知开始时:
在这里插入图片描述
对于一条边[src,dst],第i步如果可以到达src,那么第i+1步就可以到达dst。所以dp[i+1][dst]为所有第i步到达的点中有出边目的点为dst的和。然后有dp方程:
在这里插入图片描述
代码如下:

public int numWays(int n, int[][] relation, int k) {
        int[][] dp = new int[k+1][n];
        dp[0][0] = 1; // 初始化
        for (int i = 0; i < k; i++) { // 共k轮
            for (int[] edge : relation) { // 第i轮可到达每个点的路径数
                int src = edge[0];
                int des = edge[1];
                dp[i+1][des] += dp[i][src];
            } 
        }
        return dp[k][n-1];
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三更鬼

谢谢老板!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值