1.题目描述
1.1笔者解答
class Solution {
public boolean isSubPath(ListNode head, TreeNode root) {
if (head == null)
return true;
if (root == null)
return false;
//这样子如果满足条件,那么一直从根节点往下找,无法退回到以左右孩子为根节点寻找
if (root.val == head.val)
return isSubPath(head.next, root.left) || isSubPath(head.next, root.right);
else
return isSubPath(head, root.left) || isSubPath(head, root.right);
}
}
1.2笔者分析
很简单的题目,但也很容易出错,上面的代码还有两个用例没有通过,其实整个代码都是有问题的。只有一个递归是错误的,因为如果从选择根结点往下找之后,无法退回到以左右孩子为根结点寻找。以下为正确解答
class Solution {
public boolean isSubPath(ListNode head, TreeNode root) {
if(root==null)return false;
return isSubPathFromRoot(head,root)||isSubPath(head,root.left)||isSubPath(head,root.right);
}
private boolean isSubPathFromRoot(ListNode head,TreeNode root){
if(head==null)return true;
if(root==null)return false;
if(root.val==head.val)
return isSubPathFromRoot(head.next,root.left)||isSubPathFromRoot(head.next,root.right);
return false;
}
}
2.题目描述
2.1笔者分析
这题是需要往三个方向上寻找,而一个树结点只保存了左右子树的根结点,所以我们需要用一个数据结构来存储该结点第三个方向即父节点的位置,即下述代码的find方法,这也就侧面的将树结构改为了图结构,再用深度优先遍历即可,挺不错的想法。
class Solution {
private Map<TreeNode,TreeNode> parents=new HashMap<>();
private Set<TreeNode> used=new HashSet<>();
private TreeNode targetNode;
public List<Integer> distanceK(TreeNode root, TreeNode target, int K) {
find(root,null,target);
List<Integer> res=new LinkedList<>();
dfs(targetNode,res,K);
return res;
}
private void find(TreeNode root,TreeNode parent,TreeNode target){
if(null==root){return ;}
if(root.val==target.val){targetNode=root;}
parents.put(root,parent);
find(root.left,root,target);
find(root.right,root,target);
}
private void dfs(TreeNode root,List<Integer> collector,int distance){
if(root!=null&&!used.contains(root)){
used.add(root);
if(distance<=0){
collector.add(root.val);
return ;
}
dfs(root.left,collector,distance-1);
dfs(root.right,collector,distance-1);
dfs(parents.get(root),collector,distance-1);
}
}
}