欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【树】B051_LC_二叉树中所有距离为 K 的结点(广搜 + 深搜存储父节点)

程序员文章站 2023-12-27 14:08:09
...

一、Problem

给定一个二叉树(具有根结点 root), 一个目标结点 target ,和一个整数值 K 。

返回到目标结点 target 距离为 K 的所有结点的值的列表。 答案可以以任何顺序返回。

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

【树】B051_LC_二叉树中所有距离为 K 的结点(广搜 + 深搜存储父节点)
注意,输入的 “root” 和 “target” 实际上是树上的结点。
上面的输入仅仅是对这些对象进行了序列化描述。

提示:

给定的树是非空的。
树上的每个结点都具有唯一的值 0 <= node.val <= 500 。
目标结点 target 是树上的结点。
0 <= K <= 1000.

二、Solution

方法一:bfs + dfs

思路

由于 tar 结点不一定是整棵树的 root,距离为 K 的结点可能在其它子树上,所以我们需要将某个结点 node 的父亲给链接起来,于是我们利用 dfs 找到所有结点的父亲

再用 bfs 从 tar 结点开始向左子树、右子树、父亲三个方向遍历 K 次,遍历次数达到第 K 次时,队列中的结点到 tar 结点的距离就是 K

class Solution {
public:
	unordered_map<TreeNode*, TreeNode*> pars;
	void dfs(TreeNode* node, TreeNode* par) {
        if (node == NULL) return;
		pars[node] = par;
		dfs(node->left, node);
		dfs(node->right, node);
	}
    vector<int> distanceK(TreeNode* root, TreeNode* tar, int K) {
        dfs(root, NULL);
        queue<TreeNode*> q;
        unordered_map<TreeNode*, bool> vis;
        q.push(tar);
        vis[tar] = true;

        while (!q.empty()) {
        	if (K-- == 0) {
        		vector<int> ans;
        		while (!q.empty()) ans.push_back(q.front()->val), q.pop();
        		return ans;
        	} else {
        		int sz = q.size();
        		for (int i = 0; i < sz; i++) {
	        		auto cur = q.front(); q.pop();
	        		if (cur->left != NULL && !vis[cur->left])
	        			q.push(cur->left), vis[cur->left] = true;
        			if (cur->right != NULL && !vis[cur->right])
	        			q.push(cur->right), vis[cur->right] = true;
        			if (pars[cur] != NULL && !vis[pars[cur]]) 
	        			q.push(pars[cur]), vis[pars[cur]] = true;
	        	}
        	}
        }
        return {};
    }
};

复杂度分析

  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(n)O(n)
相关标签: # 树 bfs dfs

上一篇:

下一篇: