Skip to content

Files

Latest commit

c29b144 · May 17, 2024

History

History

LCP 07. 传递信息

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
May 17, 2024
Jan 13, 2024
Jan 13, 2024
Jan 13, 2024
Jan 13, 2024
Apr 18, 2024
Jan 13, 2024
Jan 13, 2024
Jan 13, 2024
Jan 13, 2024
Jan 13, 2024
comments edit_url
true

题目描述

小朋友 A 在和 ta 的小伙伴们玩传信息游戏,游戏规则如下:

  1. 有 n 名玩家,所有玩家编号分别为 0 ~ n-1,其中小朋友 A 的编号为 0
  2. 每个玩家都有固定的若干个可传信息的其他玩家(也可能没有)。传信息的关系是单向的(比如 A 可以向 B 传信息,但 B 不能向 A 传信息)。
  3. 每轮信息必须需要传递给另一个人,且信息可重复经过同一个人

给定总玩家数 n,以及按 [玩家编号,对应可传递玩家编号] 关系组成的二维数组 relation。返回信息从小 A (编号 0 ) 经过 k 轮传递到编号为 n-1 的小伙伴处的方案数;若不能到达,返回 0。

示例 1:

输入:n = 5, relation = [[0,2],[2,1],[3,4],[2,3],[1,4],[2,0],[0,4]], k = 3

输出:3

解释:信息从小 A 编号 0 处开始,经 3 轮传递,到达编号 4。共有 3 种方案,分别是 0->2->0->4, 0->2->1->4, 0->2->3->4。

示例 2:

输入:n = 3, relation = [[0,2],[2,1]], k = 2

输出:0

解释:信息不能从小 A 处经过 2 轮传递到编号 2

限制:

  • 2 <= n <= 10
  • 1 <= k <= 5
  • 1 <= relation.length <= 90, 且 relation[i].length == 2
  • 0 <= relation[i][0],relation[i][1] < n 且 relation[i][0] != relation[i][1]

解法

方法一:动态规划

我们定义 f [ i ] [ j ] 表示经过 i 轮传递到编号 j 的方案数,那么最终答案即为 f [ k ] [ n 1 ] 。初始时 f [ 0 ] [ 0 ] = 1 ,其余均为 0

i > 0 时,对于每个玩家 b ,考虑所有传递到他的玩家 a ,有 f [ i ] [ b ] = a b f [ i 1 ] [ a ] ,其中 a b 表示所有满足 a 可以传递到 b 的玩家 a

最终答案即为 f [ k ] [ n 1 ]

我们注意到 f [ i ] [ b ] 只与 f [ i 1 ] [ a ] 有关,根据状态转移方程,我们可以使用滚动数组的方式,将空间复杂度优化到 O ( n )

时间复杂度 O ( k × m ) ,空间复杂度 O ( n ) ,其中 m r e l a t i o n 的长度。

Python3

class Solution:
    def numWays(self, n: int, relation: List[List[int]], k: int) -> int:
        f = [[0] * n for _ in range(k + 1)]
        f[0][0] = 1
        for i in range(1, k + 1):
            for a, b in relation:
                f[i][b] += f[i - 1][a]
        return f[-1][-1]

Java

class Solution {
    public int numWays(int n, int[][] relation, int k) {
        int[][] f = new int[k + 1][n];
        f[0][0] = 1;
        for (int i = 1; i <= k; ++i) {
            for (int[] r : relation) {
                int a = r[0], b = r[1];
                f[i][b] += f[i - 1][a];
            }
        }
        return f[k][n - 1];
    }
}

C++

class Solution {
public:
    int numWays(int n, vector<vector<int>>& relation, int k) {
        int f[k + 1][n];
        memset(f, 0, sizeof(f));
        f[0][0] = 1;
        for (int i = 1; i <= k; ++i) {
            for (auto& r : relation) {
                int a = r[0], b = r[1];
                f[i][b] += f[i - 1][a];
            }
        }
        return f[k][n - 1];
    }
};

Go

func numWays(n int, relation [][]int, k int) int {
	f := make([][]int, k+1)
	for i := range f {
		f[i] = make([]int, n)
	}
	f[0][0] = 1
	for i := 1; i <= k; i++ {
		for _, r := range relation {
			a, b := r[0], r[1]
			f[i][b] += f[i-1][a]
		}
	}
	return f[k][n-1]
}

TypeScript

function numWays(n: number, relation: number[][], k: number): number {
    const f: number[][] = Array.from({ length: k + 1 }, () => Array(n).fill(0));
    f[0][0] = 1;
    for (let i = 1; i <= k; ++i) {
        for (const [a, b] of relation) {
            f[i][b] += f[i - 1][a];
        }
    }
    return f[k][n - 1];
}

方法二

Python3

class Solution:
    def numWays(self, n: int, relation: List[List[int]], k: int) -> int:
        f = [1] + [0] * (n - 1)
        for _ in range(k):
            g = [0] * n
            for a, b in relation:
                g[b] += f[a]
            f = g
        return f[-1]

Java

class Solution {
    public int numWays(int n, int[][] relation, int k) {
        int[] f = new int[n];
        f[0] = 1;
        while (k-- > 0) {
            int[] g = new int[n];
            for (int[] r : relation) {
                int a = r[0], b = r[1];
                g[b] += f[a];
            }
            f = g;
        }
        return f[n - 1];
    }
}

C++

class Solution {
public:
    int numWays(int n, vector<vector<int>>& relation, int k) {
        vector<int> f(n);
        f[0] = 1;
        while (k--) {
            vector<int> g(n);
            for (auto& r : relation) {
                int a = r[0], b = r[1];
                g[b] += f[a];
            }
            f = move(g);
        }
        return f[n - 1];
    }
};

Go

func numWays(n int, relation [][]int, k int) int {
	f := make([]int, n)
	f[0] = 1
	for ; k > 0; k-- {
		g := make([]int, n)
		for _, r := range relation {
			a, b := r[0], r[1]
			g[b] += f[a]
		}
		f = g
	}
	return f[n-1]
}

TypeScript

function numWays(n: number, relation: number[][], k: number): number {
    let f: number[] = new Array(n).fill(0);
    f[0] = 1;
    while (k--) {
        const g: number[] = new Array(n).fill(0);
        for (const [a, b] of relation) {
            g[b] += f[a];
        }
        f = g;
    }
    return f[n - 1];
}