题目:
Given a binary tree where every node has a unique value, and a target key k
, find the value of the nearest leaf node to target k
in the tree.
Here, nearest to a leaf means the least number of edges travelled on the binary tree to reach any leaf of the tree. Also, a node is called a leaf if it has no children.
In the following examples, the input tree is represented in flattened form row by row. The actual root
tree given 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 nearest leaf node to the target of 1.
Example 2:
Input: root = [1], k = 1 Output: 1 Explanation: The nearest leaf node is the root node itself.
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 the leaf node with value 6) is nearest to the node with value 2.
Note:
root
represents a binary tree with at least1
node and at most1000
nodes.- Every node has a unique
node.val
in range[1, 1000]
. - There exists some node in the given binary tree for which
node.val == k
.
思路:
由于在题目中,要求“travel”不仅可以从父节点到子节点,而且还可以从子节点到父节点,所以实际上是把树作为一个图来处理了。那么我们怎么做呢?我们可以额外定义一个哈希表,建立从子节点到父节点的映射。然后就可以采用BFS方法,从值为k的节点开始遍历,找到第一个叶子结点,即为我们所求。
我开始实现的代码总是无法通过大数据测试,找不到原因。后来才发现,不同节点可能会被多次加入队列,造成了重复计算。所以我后来定义了另外一个哈希表,记录已经被访问过的节点。这样节点就不会被重复访问了,可以顺利通过所有测试数据。
代码:
/**
* 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:
int findClosestLeaf(TreeNode* root, int k) {
TreeNode *node;
unordered_map<TreeNode*, TreeNode*> parent;
constructParent(root, parent, k, node);
queue<pair<TreeNode*, int>> q;
q.push(make_pair(node, 0));
if (!node->left && !node->right) {
return node->val;
}
unordered_set<TreeNode*> visited;
visited.insert(node);
while (!q.empty()) {
node = q.front().first;
int dist = q.front().second;
if (!node->left && !node->right) { // a leaf
return node->val;
}
if (parent.count(node) > 0 && visited.count(parent[node]) == 0) {
q.push(make_pair(parent[node], dist + 1));
visited.insert(parent[node]);
}
if (node->left && visited.count(node->left) == 0) {
q.push(make_pair(node->left, dist + 1));
visited.insert(node->left);
}
if (node->right && visited.count(node->right) == 0) {
q.push(make_pair(node->right, dist +1));
visited.insert(node->right);
}
q.pop();
}
return -1;
}
private:
void constructParent(TreeNode* root, unordered_map<TreeNode*, TreeNode*> &parent, int k, TreeNode* &node) {
if (root->val == k) {
node = root;
}
if (root->left) {
parent[root->left] = root;
constructParent(root->left, parent, k, node);
}
if (root->right) {
parent[root->right] = root;
constructParent(root->right, parent, k, node);
}
}
};