1. 问题描述:
给你一棵以 root 为根的二叉树和一个 head 为第一个节点的链表。
如果在二叉树中,存在一条一直向下的路径,且每个点的数值恰好一一对应以 head 为首的链表中每个节点的值,那么请你返回 True ,否则返回 False 。
一直向下的路径的意思是:从树中某个节点开始,一直连续向下的路径。
示例 1:
输入:head = [4,2,8], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
输出:true
解释:树中蓝色的节点构成了与链表对应的子路径。
示例 2:
输入:head = [1,4,2,6], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
输出:true
示例 3:
输入:head = [1,4,2,6,8], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
输出:false
解释:二叉树中不存在一一对应链表的路径。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/linked-list-in-binary-tree
2. 思路分析:
① 对于树的相关题目我们基本上是可以使用递归来实现的,对于这道题目来时也是如此,一个比较容易想到的想法是先遍历整棵二叉树,在遍历的过程中找到树中节点中等于链表中第一个元素的节点,所以我们需要声明一个List<TreeNode>类型的数据结构将递归遍历到的结果加入到这个List结构中
② 在for循环中我们将对上面递归得到的结果中的节点作为起点进行递归,因为是链表遍历起来不方便所以我们在开始的时候将链表中所有的值加入到List中,这样在递归的时候与树中的节点进行一一比对的话就很方便,我们从起点开始,当发现当前的值与链表中List对应的值相等的时候才往下进行递归,这个也是一个很好的剪枝过程,模拟的是形成符合条件的路径,递归的过程中一一比对对应位置的值,所以当发现当前的值与List对应位置的值不相等的时候那么就不用往下递归了,所以需要在方法中需要传入一个参数来记录目前相等的结果有多少个了,递归的出口判断当前得到的数字相等的数量是否等于了链表元素的数量,如果相等了那么返回true即可,所以我们在递归的过程中假如发现有一条的路径为true直接那么可以返回true了,因为只存在一条路径就符合条件了,在领扣之前的题目也遇到过类似的,像79题单词搜索,只要找到一个单词那么就直接返回true了,所以只要有一个满足条件对于有返回值的递归方法来说可以判断出当前递归下去的结果是什么假如发现true了那么就会层层返回了,就不用再尝试其他的结果了
3. 代码如下:
class Solution {
public boolean isSubPath(ListNode head, TreeNode root) {
/*将链表元素放到List中*/
dfs(root, head.val);
List<Integer> listRec = new ArrayList<>();
ListNode h = head;
while (h != null){
listRec.add(h.val);
h = h.next;
}
for (int i = 0; i < list.size(); ++i){
boolean r = find(list.get(i), listRec.size(), 0, listRec);
if (r) return true;
}
return false;
}
private boolean find(TreeNode treeNode, int size, int cur, List<Integer> listRec) {
if (size == cur) return true;
if (treeNode == null) return false;
if (listRec.get(cur) == treeNode.val){
boolean l = find(treeNode.left, size, cur + 1, listRec);
if (l) return true;
boolean r = find(treeNode.right, size, cur + 1, listRec);
if (r) return true;
}
return false;
}
/*先使用dfs找到根节点然后调用另外的递归方法检查是否满足条件*/
List<TreeNode> list = new ArrayList<>();
private void dfs(TreeNode root, int headVal) {
if (root == null) return;
if (root.val == headVal) list.add(root);
if (root.left != null) dfs(root.left, headVal);
if (root.right != null) dfs(root.right, headVal);
}
}