Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find out if a linked list is present in a given binary tree in Python
Suppose we are given a binary tree that has a root node 'root' and a linked list that has a head node 'head'. We have to find out if that linked list exists in that binary tree. If a set of nodes in the tree have links with each other in order as a linked list, and if that order is similar to that of the provided linked list, then we return 'True' or otherwise, we return 'False'.
So, if the input is like ?
Then the output will be True because the path 6?7?10 exists in the binary tree following the same sequence as the linked list.
Algorithm
To solve this, we will follow these steps ?
- Convert the linked list to an array for easier processing
- Use the KMP (Knuth-Morris-Pratt) pattern matching algorithm to efficiently search for the linked list sequence in tree paths
- Traverse the binary tree using DFS and check if any path matches the linked list sequence
- Return True if a matching path is found, False otherwise
Example
Let us see the following implementation to get better understanding ?
class TreeNode:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class ListNode:
def __init__(self, val, next=None):
self.val = val
self.next = next
def insert(temp, data):
que = []
que.append(temp)
while len(que):
temp = que[0]
que.pop(0)
if not temp.left:
if data is not None:
temp.left = TreeNode(data)
else:
temp.left = TreeNode(0)
break
else:
que.append(temp.left)
if not temp.right:
if data is not None:
temp.right = TreeNode(data)
else:
temp.right = TreeNode(0)
break
else:
que.append(temp.right)
def make_tree(elements):
node = TreeNode(elements[0])
for element in elements[1:]:
insert(node, element)
return node
def make_list(elements):
head = ListNode(elements[0])
for element in elements[1:]:
ptr = head
while ptr.next:
ptr = ptr.next
ptr.next = ListNode(element)
return head
def solve(root, head):
# Convert linked list to array
arr = []
start = head
while start:
arr.append(start.val)
start = start.next
size = len(arr)
if size == 0:
return True
# Build KMP failure function
temp_arr = [-1] * (size + 1)
for node in range(1, size + 1):
temp_arr[node] = temp_arr[node - 1] + 1
while temp_arr[node] > 0 and arr[node - 1] != arr[temp_arr[node] - 1]:
temp_arr[node] = temp_arr[temp_arr[node] - 1] + 1
def helper(root, val):
if val >= size:
return True
if not root:
return False
val += 1
while val > 0 and root.val != arr[val - 1]:
val = temp_arr[val - 1] + 1
if helper(root.left, val) or helper(root.right, val):
return True
return False
return helper(root, 0)
# Create test data
root = make_tree([6, 7, 8, 9, 10])
head = make_list([6, 7, 10])
print(solve(root, head))
The output of the above code is ?
True
How It Works
The algorithm uses the KMP pattern matching technique to efficiently search for the linked list sequence in the binary tree:
- Linked List Conversion: First, we convert the linked list into an array for easier processing
- KMP Preprocessing: We build a failure function array that helps skip unnecessary comparisons during pattern matching
- Tree Traversal: We perform a depth-first search on the binary tree, checking each path for the linked list pattern
- Pattern Matching: At each tree node, we use the KMP algorithm to efficiently determine if the current path matches the linked list sequence
Conclusion
This solution efficiently determines if a linked list exists as a path in a binary tree using the KMP algorithm. The approach provides optimal time complexity by avoiding redundant comparisons during pattern matching in tree traversal.
