二叉树中的链表
难度:
标签:
题目描述
给你一棵以 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 解释:二叉树中不存在一一对应链表的路径。
提示:
- 二叉树和链表中的每个节点的值都满足
1 <= node.val <= 100
。 - 链表包含的节点数目在
1
到100
之间。 - 二叉树包含的节点数目在
1
到2500
之间。
代码结果
运行时间: 42 ms, 内存: 16.7 MB
// Java Stream solution
// 思路:使用递归和流的组合,找到树中所有匹配链表头的节点并进一步递归检查路径。
public class Solution {
public boolean isSubPath(ListNode head, TreeNode root) {
return root != null && (dfs(root, head) || isSubPath(head, root.left) || isSubPath(head, root.right));
}
private boolean dfs(TreeNode node, ListNode head) {
if (head == null) return true;
if (node == null || node.val != head.val) return false;
return dfs(node.left, head.next) || dfs(node.right, head.next);
}
}
解释
方法:
该题解采用了深度优先搜索(DFS)的方式来判断二叉树中是否存在与链表对应的一条向下的路径。首先,题解中构建了一个失败指针(类似于KMP算法中的失配数组)来优化链表节点的比较过程。使用两个栈来模拟递归的过程,一个栈存储当前待比较的二叉树节点,另一个栈存储当前对应的链表节点。遍历二叉树的每个节点,与当前链表节点比较,如果值相同,则向下移动;如果不匹配,则使用失败指针回退到上一个可能的匹配位置。如果链表的所有节点都成功匹配,则返回真;否则,继续检查二叉树的其他路径。
时间复杂度:
O(N + L)
空间复杂度:
O(L + H)
代码细节讲解
🦆
为什么在题解中需要构建链表的失败指针数组,这种方法具体是如何优化比较过程的?
▷🦆
在题解中提到使用两个栈来模拟递归的过程,这种方法与直接使用递归相比有什么优势或不足?
▷🦆
题解中在不匹配的情况下使用失配字典回退到上一个可能的匹配位置,这种处理方式是否可能导致重复访问某些节点,从而影响效率?
▷🦆
题解中提到'如果链表的所有节点都成功匹配,则返回真',请问如果二叉树的某个分支长度小于链表长度,但开始的几个节点是匹配的,这种情况是如何处理的?
▷