Linked List in Binary Tree
MediumLinked ListTreeDepth-First SearchBinary Tree
Solution
Solution1: DFS
(Recursion
)
import { ListNode, TreeNode } from '@algorithm/lib';
export function isSubPath(head: ListNode | null, root: TreeNode | null): boolean {
if (head === null) {
return true;
}
if (root === null) {
return false;
}
const arr = [head.val];
const dp = [0];
let currentIndex = 0;
let currentNode = head.next;
while (currentNode !== null) {
while (0 < currentIndex && currentNode.val !== arr[currentIndex]) {
currentIndex = dp[currentIndex - 1];
}
currentIndex += currentNode.val === arr[currentIndex] ? 1 : 0;
arr.push(currentNode.val);
dp.push(currentIndex);
currentNode = currentNode.next;
}
function dfs(root: TreeNode | null, i: number): boolean {
if (root === null) {
return false;
}
while (0 < i && root.val !== arr[i]) {
i = dp[i - 1];
}
i += root.val === arr[i] ? 1 : 0;
return i === dp.length || dfs(root.left, i) || dfs(root.right, i);
}
return dfs(root, 0);
}
Complexity
- Time:
O(N * min(L,H))
- Space:
O(H)
Solution2: DP
import { ListNode, TreeNode } from '@algorithm/lib';
export function isSubPath(head: ListNode | null, root: TreeNode | null): boolean {
if (head === null) {
return true;
}
if (root === null) {
return false;
}
return dfs(head, root) || isSubPath(head, root.left) || isSubPath(head, root.right);
}
function dfs(head: ListNode, root: TreeNode): boolean {
if (head === null) {
return true;
}
if (root === null) {
return false;
}
return head.val === root.val && (dfs(head.next, root.left) || dfs(head.next, root.right));
}
Complexity
- Time:
O(N + L)
- Space:
O(L + H)