original text https://lwebapp.com/zh/post/l...
problem
Child A is playing A message passing game with his friends. The rules of the game are as follows:
- There are n players. All players are numbered 0 ~ n-1 respectively, of which the number of child A is 0
- Each player has A fixed number of other players who can transmit information (or not). The relationship between transmitting information is one-way (for example, A can transmit information to B, but B cannot transmit information to A).
- Each round of information must be transmitted to another person, and the information can be repeated through the same person
Given the total number of players N and A two-dimensional array relation ship composed of [player number, corresponding to transferable player number]. The number of schemes in which the return information is transmitted from small A (No. 0) to small partner No. n-1 through k rounds; If not, return 0.
Example 1:
Input: n = 5, relation = [[0,2],[2,1],[3,4],[2,3],[1,4],[2,0],[0,4]], k = 3
Output: 3
Explanation: the information starts from No. 0 of small A and passes through 3 rounds to No. 4. There are three schemes: 0 - > 2 - > 0 - > 4, 0 - > 2 - > 1 - > 4, 0 - > 2 - > 3 - > 4.
Example 2:
Input: n = 3, relation = [[0,2],[2,1]], k = 2
Output: 0
Explanation: information cannot be transferred from small A to No. 2 through 2 rounds
Restrictions:
- 2 <= n <= 10
- 1 <= k <= 5
- 1 <= relation. Length < = 90, and relation [i] length == 2
- 0 < = relation [i] [0], relation [i] [1] < n and relation [i] [0]= relation[i][1]
Solution I
Idea:
Depth first traversal (DFS) starts from position 0 to recursively find the next position. Each time the specified number of steps is found, stop. When stopping, judge whether the target position meets the requirements. If it meets the requirements, add 1 to the count.
code:
/** * DFS * @param {number} n * @param {number[][]} relation * @param {number} k * @return {number} */ var numWays = function (n, relation, k) { // Count the number of paths let ways = 0; const list = new Array(n).fill(0).map(() => new Array()); // Collect multiple transfer positions corresponding to a start position to traverse the transfer positions together for (const [from, to] of relation) { list[from].push(to); } const dfs = (index, step) => { // When the number of steps reaches the specified k steps, it is passed to the n-1 position, which meets the requirements if (step === k) { if (index === n - 1) { ways++; } // Whether the requirements are met or not, you can stop after taking k steps return; } // Recursively traverse all paths of the list const targetList = list[index]; for (const nextIndex of targetList) { dfs(nextIndex, step + 1); } }; // The first step of fixing starts from 1 dfs(0, 0); return ways; };
Solution II
Idea:
Breadth first traversal (BFS) constructs a one-dimensional array, stores all the results of traversal to step k in this array, and finally counts how many results meet the requirements.
code:
/** BFS * @param {number} n * @param {number[][]} relation * @param {number} k * @return {number} */ var numWays = function (n, relation, k) { const list = new Array(n).fill(0).map(() => new Array()); // Collect multiple transfer positions corresponding to a start position to traverse the transfer positions together for (const [from, to] of relation) { list[from].push(to); } // Pedometer let step = 0; // Start from start position 0 let queue = [0]; // 1. There is no next step, and the target does not need to be traversed // 2. When the number of steps reaches k, there is no need to traverse while (queue.length && step < k) { step++; // Obtain each position of the current queue and store all the corresponding next positions in the queue. At the same time, delete each current position because it has been passed. Here is the difference between breadth first traversal and depth first traversal const length = queue.length; for (let i = 0; i < length; i++) { let index = queue.shift(); let targetList = list[index]; for (const nextIndex of targetList) { queue.push(nextIndex); } } } // Count the number of paths let ways = 0; if (step === k) { while (queue.length) { if (queue.shift() === n - 1) { ways++; } } } return ways; };
Solution III
Idea:
Dynamic programming (DP), construct a (k + 1) * n two-dimensional array, and store the count of all results traversed to step k in this array. Finally, when viewing step k, the count of n - 1 position is the number of schemes.
such as
var n = 5, relation = [ [0, 2], [2, 1], [3, 4], [2, 3], [1, 4], [2, 0], [0, 4], ], k = 3;
Construct a 4 * 5 array. From step 0, arr[0][0] is counted as 1
0: (5) [1, 0, 0, 0, 0] 1: (5) [0, 0, 0, 0, 0] 2: (5) [0, 0, 0, 0, 0] 3: (5) [0, 0, 0, 0, 0]
first round
0: (5) [1, 0, 0, 0, 0] 1: (5) [0, 0, 1, 0, 1] 2: (5) [0, 0, 0, 0, 0] 3: (5) [0, 0, 0, 0, 0]
Second round
0: (5) [1, 0, 0, 0, 0] 1: (5) [0, 0, 1, 0, 1] 2: (5) [1, 1, 0, 1, 0] 3: (5) [0, 0, 0, 0, 0]
Third round
0: (5) [1, 0, 0, 0, 0] 1: (5) [0, 0, 1, 0, 1] 2: (5) [1, 1, 0, 1, 0] 3: (5) [0, 0, 1, 0, 3]
Finally, at the end of the third round, the number of schemes reaching n - 1 is 3
code:
/** * @param {number} n * @param {number[][]} relation * @param {number} k * @return {number} */ var numWays = function (n, relation, k) { const dp = new Array(k + 1).fill(0).map(() => new Array(n).fill(0)); dp[0][0] = 1; for (let i = 0; i < k; i++) { for (const [src, dst] of relation) { dp[i + 1][dst] += dp[i][src]; } } return dp[k][n - 1]; };
More leetcode algorithm solutions, leetcode Brush problem notes and explain classical algorithms https://lwebapp.com/zh/tag/le...