Example 2:
Input: head = [1,4,2,6], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
Output: true
Example 3:
Input: head = [1,4,2,6,8], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
Output: false
Explanation: There is no path in the binary tree that contains all the elements of the linked list from head.
Constraints:
-
The number of nodes in the tree will be in the range
[1, 2500]
. -
The number of nodes in the list will be in the range
[1, 100]
. -
1 <= Node.val <= 100
for each node in the linked list and binary tree.
方法一:自己写的,DFS + 暴力算法。
方法二:自己写的,KMP + DFS。
方法三:别人写的,DFS + 暴力算法。
方法四:别人写的,KMP + DFS。
import java.util.ArrayList;
import java.util.List;
import com.lun.util.BinaryTree.TreeNode;
import com.lun.util.SinglyLinkedList.ListNode;
public class LinkedListInBinaryTree {
//方法一:自己写的,DFS + 暴力算法
public boolean isSubPath(ListNode head, TreeNode root) {
if(root == null) return false;
return helper(head, root) || isSubPath(head, root.left) || isSubPath(head, root.right);
}
private boolean helper(ListNode head, TreeNode root) {
if(head != null && root == null)
return false;
if(head != null && root != null) {
if(head.val != root.val)
return false;
return helper(head.next, root.left) || helper(head.next, root.right);
}
return true;
}
//方法二:自己写的,KMP + DFS
public boolean isSubPath2(ListNode head, TreeNode root) {
int[][] patternAndNext = getPatternAndNext(head);
return helper(patternAndNext, root, -1);
}
private boolean helper(int[][] patternAndNext, TreeNode node, int j) {
if(node == null) return false;
int[] pattern = patternAndNext[0], next = patternAndNext[1];
while(j >= 0 && node.val != pattern[j + 1])
j = next[j];
if(node.val == pattern[j + 1])
j++;
if(j == patternAndNext[0].length - 1)
return true;
return helper(patternAndNext, node.left, j) || helper(patternAndNext, node.right, j);
}
//KMP算法
private int[][] getPatternAndNext(ListNode head){
int count = 0;
ListNode p = head;
while(p != null) {
count++;
p = p.next;
}
int[] pattern = new int[count];
p = head;
count = 0;
while(p != null) {
pattern[count++] = p.val;
p = p.next;
}
int[] next = new int[count];
//正戏
int j = -1;
next[0] = j;
for(int i = 1; i < pattern.length; i++) {
while(j >= 0 && pattern[i] != pattern[j + 1])
j = next[j];
if(pattern[i] == pattern[j + 1])
j++;
next[i] = j;
}
return new int[][] {pattern, next};
}
//方法三:别人写的,DFS + 暴力算法
public boolean isSubPath3(ListNode head, TreeNode root) {
if (head == null) return true;
if (root == null) return false;
return dfs(head, root) || isSubPath(head, root.left) || isSubPath(head, root.right);
}
private boolean dfs(ListNode head, TreeNode root) {
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));
}
//方法四:别人写的,KMP + DFS
public boolean isSubPath4(ListNode head, TreeNode root) {
List A = new ArrayList<>(), dp = new ArrayList<>();
A.add(head.val);
dp.add(0);
int i = 0;
head = head.next;
while (head != null) {
while (i > 0 && head.val != A.get(i))
i = dp.get(i - 1);
if (head.val == A.get(i)) ++i;
A.add(head.val);
dp.add(i);
head = head.next;
}
return dfs(root, 0, A, dp);
}
private boolean dfs(TreeNode root, int i, List A, List dp) {
if (root == null) return false;
while (i > 0 && root.val != A.get(i))
i = dp.get(i - 1);
if (root.val == A.get(i)) ++i;
return i == dp.size() || dfs(root.left, i, A, dp) || dfs(root.right, i, A, dp);
}
}
import static org.junit.Assert.*;
import org.junit.Test;
import com.lun.util.BinaryTree;
import com.lun.util.BinaryTree.TreeNode;
import com.lun.util.SinglyLinkedList;
import com.lun.util.SinglyLinkedList.ListNode;
public class LinkedListInBinaryTreeTest {
@Test
public void test() {
LinkedListInBinaryTree lObj = new LinkedListInBinaryTree();
TreeNode root1 = BinaryTree.of(1, 4, 4, null, 2, 2, null, 1, null, 6, 8, //
null, null, null, null, 1, 3);
ListNode head1 = SinglyLinkedList.of(4, 2, 8);
assertTrue(lObj.isSubPath(head1, root1));
ListNode head2 = SinglyLinkedList.of(1, 4, 2, 6);
assertTrue(lObj.isSubPath(head2, root1));
ListNode head3 = SinglyLinkedList.of(1, 4, 2, 6, 8);