有向图 最长环的长度

134 阅读1分钟

题目

8c1642215b08bae1007c1e84bcb2356d.png

  • 根据有向图,根据有向图遍历每一个节点,每遍历一次节点编号+1,并记录起始点编号,如果存在环,那么一定会和已经编号的节点相交,结算环的长度
  • 如果存在未计算过的环,那么环最后的编号一定大于当前节点的起始编号
  • 如果是存在过的环或者来到遍历过的节点,遇到的节点编号一定小于起始编号

image.png

function process(edges) {
  let n = edges.length;
  // 每个节点的id
  const ids = Array(n).fill(0);
  let ans = -1;
  // 每个节点的编号
  let number = 1;

  // 遍历每个节点找环
  for (let from = 0; from < n; from++) {
    // 当前节点未被遍历过
    if (ids[from] === 0) {
      // 记录起始点编号
      let fromId = number;
      // 根据有向图依次查找节点,如果遇到 -1 说明不是环,直接退出
      for (let current = from; current !== -1; current = edges[current]) {
        // 如果存在环,那么一定会和之前已经遍历过的节点相交,结算环的长度
        if (ids[current] > 0) {
          // 情况1:如果当前环没结算过长度,那么起始点编号一定小于环的截止编号
          // 情况2:如果当前节点指向了已经遍历过的节点,那么起始点编号一定大于遍历过的节点编号,所以不会进 if
          if (fromId <= ids[current]) {
            ans = Math.max(ans, number - ids[current]);
          }
          break;
        }
        ids[current] = number++;
      }
    }
  }
}