思路:先找到父,然后做类似爆炸的寻找,看成图去找
思路2还没写:1 用O(n)把树打成数组 ,转换过程中如果找到target 就记录数组下标 2 根据当前target 进行运算 找 父节点 左右叶子节点,带入k 当k为0 说明算出一个解 3 循环get解-也就是数组下标,不为空就是有解
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> distanceK(TreeNode root, TreeNode target, int k) {
List<Integer> list = new ArrayList<>();
//找到当前节点以及父节点
Map<TreeNode, TreeNode> map =new HashMap<>();
getFather(root, target,map);
//根据父节点找相邻
getFatherNbh( target, map, k,list);
//根据当前节点的下节点找
getNbh(target, k, 0,list);
return list;
}
//找父亲距离k的
private void getFatherNbh( TreeNode target, Map<TreeNode, TreeNode> map, int k,List<Integer> list) {
boolean a = true;
TreeNode nodeBox = target;
//找父节点一直到没有为止
while (a){
TreeNode father = map.get(nodeBox);
if (father != null) {
k--;
if (k == 0) {
list.add(father.val);
return;
}
//判断是左节点还是右节点
if (father.left != null) {
if (father.left.val != nodeBox.val) {
getNbh(father,k,1,list);
}
}
if (father.right != null) {
if (father.right.val != nodeBox.val) {
getNbh(father,k,2,list);
}
}
nodeBox = father;
}else {
a=false;
}
}
}
//找出当前节点下的 所有k步能到的
private void getNbh(TreeNode target, int k, int i,List<Integer> list) {
//i 0 代表说有 1 代表左边 2 代表右边
if (target == null) {
return;
}
if (k == 0) {
list.add(target.val);
return;
}
if (i == 0||i==1) {
getNbh(target.left,k-1,0,list);
}
if (i == 0||i==2) {
getNbh(target.right,k-1,0,list);
}
}
/**
* 找爸爸
*
* @param root
* @param target
* @return
*/
private TreeNode getFather(TreeNode root, TreeNode target,Map<TreeNode, TreeNode> map) {
if (root == null) {
return null;
}
TreeNode l = getFather(root.left,target,map);
TreeNode r = getFather(root.right,target,map);
if (l != null) {
map.put(l,root);
return root;
}
if (r != null) {
map.put(r,root);
return root;
}
if (root.val == target.val) {
return target;
}
return null;
}
}