自学内容网 自学内容网

学习记录:js算法(五十七):二叉树中所有距离为 K 的结点

二叉树中所有距离为 K 的结点

给定一个二叉树(具有根结点 root), 一个目标结点 target ,和一个整数值 k ,返回到目标结点 target 距离为 k 的所有结点的值的数组。(可以任意顺序返回)

图一:
在这里插入图片描述

示例 1:
输入:root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, k = 2
输出:[7,4,1]
解释:所求结点为与目标结点(值为 5)距离为 2 的结点,值分别为 7,4,以及 1

示例 2:
输入: root = [1], target = 1, k = 3
输出: []

我的思路
没有思路,完全不会写
网上思路
递归、栈

网上思路

递归
var distanceK = function (root, target, k) {
    const parentMap = new Map();

    // 构建父节点映射
    function buildParentMap(node, parent) {
        if (!node) return;
        parentMap.set(node, parent);
        buildParentMap(node.left, node);
        buildParentMap(node.right, node);
    }

    buildParentMap(root, null);

    // 找到目标节点
    let targetNode = null;
    function findTarget(node) {
        if (!node) return;
        if (node === target) {
            targetNode = node;
            return;
        }
        findTarget(node.left);
        findTarget(node.right);
    }

    findTarget(root);

    // BFS 找到距离为 k 的节点
    const result = [];
    const visited = new Set();
    const queue = [[targetNode, 0]]; // [节点, 当前距离]
    visited.add(targetNode);

    while (queue.length > 0) {
        const [currentNode, currentDistance] = queue.shift();

        if (currentDistance === k) {
            result.push(currentNode.val);
        }

        // 遍历子节点
        if (currentNode.left && !visited.has(currentNode.left)) {
            visited.add(currentNode.left);
            queue.push([currentNode.left, currentDistance + 1]);
        }

        if (currentNode.right && !visited.has(currentNode.right)) {
            visited.add(currentNode.right);
            queue.push([currentNode.right, currentDistance + 1]);
        }

        // 遍历父节点
        const parentNode = parentMap.get(currentNode);
        if (parentNode && !visited.has(parentNode)) {
            visited.add(parentNode);
            queue.push([parentNode, currentDistance + 1]);
        }
    }

    return result;
};

讲解
distanceK 函数:

  1. buildParentMap 函数通过 DFS 遍历树,并记录每个节点的父节点。
  2. findTarget 函数找到目标节点。
  3. 使用 BFS 从目标节点开始,记录当前节点的距离,并将距离为 k 的节点值添加到结果数组中。
  4. 返回结果数组。

var distanceK = function (root, target, k) {
    const parentMap = new Map();
    const stack = [root];

    // DFS to record parent pointers
    while (stack.length) {
        const node = stack.pop();
        if (node.left) {
            parentMap.set(node.left, node);
            stack.push(node.left);
        }
        if (node.right) {
            parentMap.set(node.right, node);
            stack.push(node.right);
        }
    }

    const result = [];
    const visited = new Set();
    const queue = [[target, 0]]; // [node, current distance]

    // BFS to find nodes at distance k
    while (queue.length) {
        const [node, dist] = queue.shift();
        if (visited.has(node)) {
            continue;
        }
        visited.add(node);

        if (dist === k) {
            result.push(node.val);
        }

        // Explore neighbors: left, right, and parent
        if (node.left && !visited.has(node.left)) {
            queue.push([node.left, dist + 1]);
        }
        if (node.right && !visited.has(node.right)) {
            queue.push([node.right, dist + 1]);
        }
        const parent = parentMap.get(node);
        if (parent && !visited.has(parent)) {
            queue.push([parent, dist + 1]);
        }
    }

    return result;
};

讲解
distanceK 函数

  1. 使用一个栈来进行深度优先搜索(DFS),遍历整个树并记录每个节点的父节点。
  2. 使用一个队列进行广度优先搜索(BFS),从目标节点开始,寻找距离为 k 的节点。
  3. BFS 中,我们检查当前节点的左子节点、右子节点和父节点。
  4. 如果当前距离等于 k,则将节点的值添加到结果数组中。

总结

没有思路,全靠网上的写法


原文地址:https://blog.csdn.net/weixin_48677331/article/details/142707997

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!