Leetcode863:二叉树中所有距离为k的节点

Leetcode863: 哈希表、队列、哈希集合

题目描述:二叉树中所有距离为k的节点。

要找到二叉树中和某个节点距离为k的所有节点,返回节点对应的值列表。

解题思路

二叉树 r o o t root root中给定一个 t a r g e t target target节点,要找到和其距离为k的节点,首先找到和 t a r g e t target target距离为0的节点,然后向外扩充找到距离为1的节点,接着找距离为2的节点,直到找到所有距离为k的节点。用到了数学归纳法的思想。
数学归纳法:假设已经找到了所有距离为k-1的节点,对于其中的每个节点,找到和其距离为1的节点,即为和target距离为k的节点。 而对于每个节点,要找到和其距离为1的节点,除了左右子树外,还有父节点,所以可以用一个哈希表 将每个节点的父节点存下来,存储的方法递归遍历即可。
逐层查找:之前遍历过的k-1距离节点存在哪里?这里k-1距离节点在之前被查找出来,现在要用其找下一层节点,是先进先出的需求,所以用队列来存储之前查找距离时遍历过的所有节点。
哈希去重:假设某个节点向外扩充时已经扩充过左子树,下次扩充左子树的时候就不应该再对其父节点进行扩充,所以这里可以用一个哈希集 来记录已经扩充过的节点。
逐层遍历分层小技巧:从 队列 中取数遍历的时候如何判断已经取到了距离为k-1的最后一个节点?可以在遍历每一层距离的开始前插入一个 n u l l p t r nullptr nullptr节点,当遍历到 n u l l p t r nullptr nullptr时则说明队列中剩余节点都是距离为某一定值的节点。

代码演示

实现语言:c++(理由:python太高级,很多计算机程序内部的一些经典操作都成了傻瓜式代码;c语言太低级,例如哈希表、队列等都没有封装好的结构)。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void  dfs(TreeNode *root, TreeNode *par, unordered_map<TreeNode *, TreeNode *> &parent) {
        if (root == nullptr) return;
        parent[root] = par;
        dfs(root->left, root, parent);
        dfs(root->right, root, parent);
    }
    vector<int> distanceK(TreeNode* root, TreeNode* target, int k) {
        unordered_map<TreeNode *, TreeNode *> parent;
        unordered_set<TreeNode *> set;
        queue<TreeNode *> que;
        dfs(root, nullptr, parent);
        vector<int> ans;
        que.push(nullptr);
        que.push(target);
        set.insert(nullptr);
        set.insert(target);
        int dist = 0;
        while (!que.empty()) {
            TreeNode *node = que.front();
            que.pop();
            if (node == nullptr) {
                // printf(" find null : k %d\n", dist);
                if (dist == k) {
                    while (!que.empty()){
                        TreeNode *temp = que.front();
                        que.pop();
                        ans.push_back(temp->val);
                    }
                    return ans;
                }else {
                    que.push(nullptr);
                    dist++;
                }
            }else {
                if (set.find(node->left) == set.end()) {
                    set.insert(node->left);
                    que.push(node->left);
                }
                if (set.find(node->right) == set.end()) {
                    set.insert(node->right);
                    que.push(node->right);
                }
                if (set.find(parent[node]) == set.end()) {
                    set.insert(parent[node]);
                    que.push(parent[node]);
                }
            }
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值