742. Closest Leaf in a Binary Tree
· User Accepted:351
· User Tried:667
· Total Accepted:356
· Total Submissions:1586
· Difficulty:Medium
Given a binary tree whereevery node has a unique value, and a target key k, findthe value of the closest leaf node to target k in thetree.
Here, closest to aleaf means the least number of edges travelled on the binary tree to reach anyleaf of the tree. Also, a node is called aleaf if ithas no children.
In the following examples, the input tree isrepresented in flattened form row by row. The actual root treegiven will be a TreeNode object.
Example 1:
Input:
root = [1, 3, 2], k = 1
Diagram of binary tree:
1
/ \
3 2
Output: 2 (or 3)
Explanation: Either 2 or 3 is the closest leaf nodeto the target of 1.
Example 2:
Input:
root = [1], k = 1
Output: 1
Explanation: The closest leaf node is the root nodeitself.
Example 3:
Input:
root = [1,2,3,4,null,null,null,5,null,6], k = 2
Diagram of binary tree:
1
/ \
2 3
/
4
/
5
/
6
Output: 3
Explanation: The leaf node with value 3 (and not theleaf node with value 6) is closest to the node with value 2.
Note:
1. root representsa binary tree with at least 1 nodeand at most 1000 nodes.
2. Every node has a unique node.val inrange [1, 1000].
3. There exists some node in the given binary tree forwhich node.val == k
思路:
这题就是说给你一颗树,树的每一个节点都有一个独一无二的value,给你一个初始的value,输出距离这个value最近的叶子节点的value
哎 这题我把题目看错了,whereevery node has a unique value,然后又说Thereexists some node in the given binary tree for which node.val == k,把题目看因此我以为有多个value为k节点,然后输出距离这些k节点集合距离最近的叶子节点的编号,按照这种思路来做题,题目会变得超复杂,我是先把树转换成无向图,然后对每一个编号为k的节点来进行广度优先遍历,找到距离所有的K节点距离最近的那个叶子节点的编号。
按照这种复杂的理解,我还真的做出来了一种复杂的aC的解法,通过这个过程,我学会了如何将树转换成无向图,有两种方法,一种是实用c++语言自带的queue队列来广度遍历,通过一系列的条件判断来实现树转换成无向图,第二种方法是实用自己写的队列,在这个队列中,所有为空的节点都要在队列中,这样的话能够很方便的得到任意编号节点的父节点,这里我使用了方法一。
在之后我又按照正确的思路,也就是只有一个K节点的情况来完成题目的ac,当只有一个K节点的时候情况会简单很多,因为在这种情况下可以使用深度优先遍历DP来解决题目:
错误理解方法:
classSolution {
#include <queue>
public:
int getIndex(TreeNode * p, int k,int &theKCount)
{
return p->val == k ? (theKCount++) +1000 : p->val;
}
int findClosestLeaf(TreeNode* root, int k){
vector<int> edges[2002];
queue<TreeNode *> theDuilie;
queue<int> theGDuilie;
bool vst[2002] = { false };
int time[2002] = { 0 };
int nearLeefNum, nearLeefLength;
nearLeefLength = 3000;
if (root ->left == NULL &&root->right == NULL)
{
return root->val;
}
theDuilie.push(root); TreeNode * q, *p; q =p= root;
int theKCount = 1;
root->val = getIndex(root, k,theKCount);
int theRootIndex = root->val;
if (root->left != NULL)
{
root->left->val =getIndex(root->left, k, theKCount);
edges[root->val].push_back(root->left->val);
}
if (root->right != NULL)
{
root->right->val =getIndex(root->right, k, theKCount);
edges[root->val].push_back(root->right->val);
}
while (!theDuilie.empty())
{
p = theDuilie.front();
theDuilie.pop();
if (p->left != NULL)
{
theDuilie.push(p->left);
edges[p->left->val].push_back(p->val);
if (p->left->left!= NULL)
{
p->left->left->val= getIndex(p->left->left, k, theKCount);
edges[p->left->val].push_back(p->left->left->val);
}
if(p->left->right != NULL)
{
p->left->right->val= getIndex(p->left->right, k, theKCount);
edges[p->left->val].push_back(p->left->right->val);
}
}
if (p->right != NULL)
{
theDuilie.push(p->right);
edges[p->right->val].push_back(p->val);
if(p->right->left != NULL)
{
p->right->left->val= getIndex(p->right->left, k, theKCount);
edges[p->right->val].push_back(p->right->left->val);
}
if(p->right->right != NULL)
{
p->right->right->val= getIndex(p->right->right, k, theKCount);
edges[p->right->val].push_back(p->right->right->val);
}
}
}
for (int i = 1; i < theKCount; i++)
{
memset(time, 0, sizeof(time));
memset(vst, false,sizeof(vst));
time[1000 + i] = 0;
int index;
theGDuilie.push(1000 + i);
while (!theGDuilie.empty())
{
index =theGDuilie.front(); theGDuilie.pop();
int u;
vst[index] = true;
if(edges[index].size() == 1 && index != theRootIndex)
{
time[index] =0;
return k;
}
for (int i = 0; i <edges[index].size(); i++)
{
u =edges[index][i];
if (!vst[u])
{
theGDuilie.push(u);
vst[u]= true;
time[u]= time[index] + 1;
if(edges[u].size() == 1 && u != theRootIndex)
{
if(time[u] < nearLeefLength)
{
nearLeefNum= u;
nearLeefLength= time[u];
gotonext;
}
}
}
}
}
next:;
while (!theGDuilie.empty())
{
theGDuilie.pop();
}
}
if (nearLeefNum > 1000) return k;
else
{
return nearLeefNum;
}
}
};
只有一个K正确理解的方法:
这里可以用dp解决,代码如下
通过这个编程我学会了结构体的对象可以向函数传引用,在函数里面可以对引用进行操作,就相当于直接对类的对象进行了操作
class Solution {
#include <queue>
public:
struct Cell {
intnum;
intlength;
boolisFound;
Cell(intx,int length,bool isFound) : num(x), length(length), isFound(isFound) {}
};
Cell foundTheLeef(TreeNode * p, int k,Cell &ref)
{
if(p == NULL) return Cell(-1, 2000, false);
if(p->left == NULL&&p->right==NULL)
{
if(p->val == k)
{
ref= Cell(k, 0, true);
returnref;
}
returnCell(p->val, 0, false);
}
Cellleft = foundTheLeef(p->left, k, ref);
if(ref.length == 0&&ref.isFound) return Cell(-1, 2000, false);
Cellright = foundTheLeef(p->right, k, ref);
if(ref.length == 0&&ref.isFound) return Cell(-1, 2000, false);
if(p->val == k)
{
if(left.length <= right.length)
{
ref= Cell(left.num, left.length + 1, true);
}
else
{
ref= Cell(right.num, right.length + 1, true);
}
returnCell(p->val, 1, true);
}
if(!left.isFound && !right.isFound)
{
if(left.length <= right.length)
{
return Cell(left.num, left.length + 1, false);
}
else
{
return Cell(right.num, right.length + 1, false);
}
}
if(left.isFound)
{
if(ref.length > left.length +right.length+1)
{
ref= Cell(right.num, left.length +right.length+1, true);
}
returnCell(left.num, left.length+1, true);
}
else
{
if(ref.length > right.length +left.length+1)
{
ref= Cell(left.num, right.length +left.length+1, true);
}
returnCell(right.num, right.length + 1, true);
}
}
int findClosestLeaf(TreeNode* root, int k) {
Cell ref = Cell(-1, 2000, false);
foundTheLeef(root,k, ref);
return ref.num;
}
};