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

题目

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

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

理解

虽然题目很简洁,理解也好理解,但不知道怎么做啊~~
看了几个别人的代码,有一个个思路

  • 先把二叉树转为图,再进行广度优先遍历,找出距离为k的结点。因为二叉树只能通过父节点访问子结点,是单向的;而图可以双向访问,所以要把树转为图。其次,以一个结点为中心扩散寻找与他相距为k的结点显然用广度优先遍历。

代码

理解了一下别人的

/*
map容器:一对多映射,基于关键字快速查找,不允许重复值,映射关系,键和值对应
set容器:内部自动有序不允许有重复值的
queue:相当于队列,先进先出
*/

struct TreeNode {
	int val;
	TreeNode* left;
	TreeNode* right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Solution {
public:
    //给map写入父节点
	void setFather(TreeNode* root, TreeNode* father, map<TreeNode*, TreeNode*>& fatherMap) {
		if (root == NULL) return;
		if (father != NULL) fatherMap.insert({ root,father });
		setFather(root->left, root, fatherMap);
		setFather(root->right, root, fatherMap);
	}
    //
	vector<int> distanceK(TreeNode * root, TreeNode * target, int K) {
		map<TreeNode*, TreeNode*> fatherMap; //用一个map存放每个节点及其对应的父节点
		setFather(root, NULL, fatherMap);  //设置每个节点的父节点
		queue<TreeNode*> q;  //层序遍历/广度优先搜索
		set<TreeNode*> s;  //存放已经访问过的节点
		q.push(target);  //以target为起点扩散搜索距离它K的节点
		s.insert(target);
		while (!q.empty() && K) {
			K--;
			int num = q.size();
			for (int i = 0; i < num; i++) {
				TreeNode* temp = q.front();
				q.pop();
				//向左右子节点扩散
				if (temp->left != NULL && s.find(temp->left) == s.end()) {
					q.push(temp->left);
					s.insert(temp->left);
				}
				if (temp->right != NULL && s.find(temp->right) == s.end()) {
					q.push(temp->right);
					s.insert(temp->right);
				}
				//向父节点扩散
				if (fatherMap.count(temp) && s.find(fatherMap[temp]) == s.end()) {
					q.push(fatherMap[temp]);
					s.insert(fatherMap[temp]);
				}
			}
		}
		vector<int> ans;  //最后队列中剩余的节点既是扩散至第K层的所有节点
		while (!q.empty()) {
			ans.push_back(q.front()->val);
			q.pop();
		}
		return ans;
	}
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值