Breadth first search depth first search dynamic programming LeetCode topic: transmitting information

Posted by koglakci on Tue, 01 Mar 2022 08:20:37 +0100

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:

  1. There are n players. All players are numbered 0 ~ n-1 respectively, of which the number of child A is 0
  2. 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).
  3. 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...

reference resources

Topics: Algorithm leetcode dfs dp bfs