LeetCode - Medium - 1367

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.

Analysis


方法一:自己写的,DFS + 暴力算法。

方法二:自己写的,KMP + DFS。

方法三:别人写的,DFS + 暴力算法。

方法四:别人写的,KMP + DFS。

Submission


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);

}

}

Test


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);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值