86 lines
2.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* // Definition for a _Node.
* function _Node(val, neighbors) {
* this.val = val === undefined ? 0 : val;
* this.neighbors = neighbors === undefined ? [] : neighbors;
* };
* https://leetcode.cn/problems/clone-graph/?envType=study-plan-v2&envId=top-interview-150
*/
/**
* @param {_Node} node
* @return {_Node}
*/
const cloneGraph = function (node) {
};
// eslint-disable-next-line no-underscore-dangle, no-unused-vars
function _Node(val, neighbors) {
this.val = val === undefined ? 0 : val;
this.neighbors = neighbors === undefined ? [] : neighbors;
}
/*
只给了我们一个连通图的一个节点,叫我们克隆整个图,根据两图图的定义,从这个节点出发我们能到达途中的任意一个节点(顶点)
所以我们只需要遍历所有的neighbor然后顺着邻居继续遍历邻居即可遍历整个图但是这里有一个问题就是如果通过邻居到达了
自己,或者邻居的邻居,是自己的邻居,就会发生循环,这里就遇到使用一种数据结果来缓存已经遍历过的邻居,当再次遇到它时跳过就行。
抽象过程:你需要统计小王家人,你只认识小王,于是题通过小王认识了它的爸爸,妈妈,把他们加入到统计表,然后小王的爸爸向你介绍了
它的妹妹,同时小王向你介绍了它的姑姑,但是你发现这两个人是同一个人,所以你只统计了一次,最后你就获得了所有和小王有关的人。
*/
function f1(node) {
const visited = new Map(); // 储存原节点,和克隆节点的映射
/**
*
* @param {*} node 需要克隆的节点
* @returns 返回克隆的节点
*/
function clone(node) {
if (!node) return node;
// 如果这个节点之前克隆过,直接返回其克隆节点
if (visited.has(node)) return visited.get(node);
// 创建这个节点的克隆节点
const cloneNode = new _Node(node.val, []);
// node与cloneNode建立映射
visited.set(node, cloneNode);
// 为克隆节点克隆邻居节点
for (const neighbor of node.neighbors) {
cloneNode.neighbors.push(clone(neighbor));
}
return cloneNode;
}
return clone(node);
}
/*
思路和上面一致但是使用广度优先遍历
*/
function f2(node) {
if (!node) return node;
const visited = new Map();
const queue = [node]; // 用于广度遍历
const cNode = new _Node(node.val, []);
visited.set(node, cNode); // 克隆第一个节点将其存入visited
while (queue.length > 0) {
const n = queue.shift();
// 遍历这个节点的所有邻居如果没有访问过将其clone并加入visited
for (const neighbor of n.neighbors) {
if (!visited.has(neighbor)) {
visited.set(neighbor, new _Node(neighbor.val, []));
queue.push(neighbor);
}
visited.get(n).neighbors.push(visited.get(neighbor));
}
}
return cNode;
}