Skip to content

Commit

Permalink
修改
Browse files Browse the repository at this point in the history
  • Loading branch information
arkingc committed Jul 9, 2018
1 parent 5b3d135 commit 48450fe
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 0 deletions.
Binary file added pic/leetcode-863-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
121 changes: 121 additions & 0 deletions 数据结构与算法/算法题总结.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@
- *路径*
+ 《剑指offer》面试题34:[二叉树中和为某一值的路径](#二叉树中和为某一值的路径)(`回溯`)
+ Leetcode124:[二叉树的最大路径和](#二叉树的最大路径和)(`动态规划` `后序` `hard`)
+ Leetcode863:[二叉树中与target距离为K的结点](#二叉树中与target距离为k的结点)(`DFS(前序)` `BFS` `medium`)
- *深度*
+ 《剑指offer》面试题55(题目一):[二叉树的深度](#二叉树的深度)(`递归`)
+ 《剑指offer》面试题55(题目二):[平衡二叉树AVL](#平衡二叉树avl)(`后序`)
Expand Down Expand Up @@ -12243,5 +12244,125 @@ private:
};
```

<br>
<br>

## 二叉树中与target距离为K的结点

[OJ链接](https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/description/)

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

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

示例 1:

```
输入:root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, K = 2

输出:[7,4,1]
```

![](../pic/leetcode-863-1.png)

提示:

1. 给定的树是非空的,且最多有 `K` 个结点。
2. 树上的每个结点都具有唯一的值 `0 <= node.val <= 500` 。
3. 目标结点 `target` 是树上的结点。
4. `0 <= K <= 1000`.

### 解答

使用DFS(前序)遍历二叉树,得到从`root`到`target`的路径,假设路径如下:

```
root
/
nd1
\
nd2
\
target
```

那么所有与`target`距离为`K`的节点就是:

1. 以`target`为根节点的子树中,深度为`K`的节点
2. 以`nd2->left`为根节点的子树中,深度为`K-2`的节点
3. 以`nd1->left`为根节点的子树中,深度为`K-3`的节点
4. 以`root->right`为根节点的子树中,深度为`K-4`的节点
5. 除此之外,在`root`到`target`的路径上的节点,也可以满足要求。比如`K=1`时,`nd2`要添加到结果中,`K=2`时,`nd1`要添加到结果中...

这个过程可以通过BFS完成

* 时间复杂度:O(n)(DFS时每个节点最多遍历一次,BFS中,每个节点最多也只遍历一次)
* 空间复杂度:O(n)(需要使用一个vector保存路径,BFS时需要一个队列保存节点)

```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:
vector<int> distanceK(TreeNode* root, TreeNode* target, int K) {
vector<TreeNode*> path;
vector<int> res;
//使用dfs获取root到target的路径,返回false时,路径不存在,即输入不合法
if(!dfs(root,target,path)) return res;

//使用bfs将以第一个参数为根节点的子树中,深度为K的节点添加到结果res中
bfs(target,res,K);
for(int i = path.size() - 2;i >= 0 && K > 0;i--){
TreeNode *nd = path[i],*child = nd->left == path[i + 1] ? nd->right : nd->left;
if(--K == 0) res.push_back(nd->val);
bfs(child,res,K - 1);
}

return res;
}
private:
bool dfs(TreeNode *root,TreeNode *target,vector<TreeNode*> &path){
if(!root) return false;

path.push_back(root);

if(root == target)
return true;

if(dfs(root->left,target,path)) return true;
if(dfs(root->right,target,path)) return true;

path.pop_back();

return false;
}

void bfs(TreeNode *root,vector<int> &res,int k){
if(!root || k < 0) return;

deque<TreeNode*> d;
d.push_back(root);

while(!d.empty() && k--){
for(int count = d.size();count > 0;count--){
TreeNode *nd = d.front();
d.pop_front();
if(nd->left) d.push_back(nd->left);
if(nd->right) d.push_back(nd->right);
}
}

for(TreeNode *nd : d) res.push_back(nd->val);
}
};
```

<br>
<br>

0 comments on commit 48450fe

Please sign in to comment.