Sublist Search (Search a linked list in another list)
Given two linked lists, the task is to check whether the first list is present in 2nd list or not.
Examples:
Input: list1 = 10->20, list2 = 5->10->20
Output : Yes
Explanation: 5 -> 10 -> 20Input: list1 = 1->2, list2 = 1->2->1->2->3->4
Output: Yes
Explanation: 1 -> 2 -> 1 -> 2 -> 3 -> 4Input: list1 = 1->2->3->4, list2 = 1->2->2->1->2->3
Output: No
Explanation: List 1 is not present in List 2.
[Naive Approach] Using Iterative Method - O(n * m) time and O(1) space
The idea is to use a nested loop approach where we consider each node in the second list as a potential starting point for finding the first list. For each such starting point, we try to match the sequences of both lists, advancing through them simultaneously, and if the entire first list can be traversed while matching values with a consecutive portion of the second list, then the first list is indeed a sub list of the second.
// C++ program to search a linked list in another list
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node* next;
Node (int x) {
data = x;
next = nullptr;
}
};
bool isSubList(Node* list1, Node* list2) {
Node* head2 = list2;
// Starting from each node of list2
while (head2 != nullptr) {
Node* head1 = list1;
Node* curr = head2;
// Check if list1 is present
// starting from node head2.
while (curr != nullptr && head1 != nullptr
&& head1->data == curr->data) {
curr = curr->next;
head1 = head1->next;
}
// If list1 is completely traversed, it means
// it is present in list2.
if (head1 == nullptr) return true;
// Else, move to the next node of list2.
head2 = head2->next;
}
// If list1 is not present in list2
return false;
}
int main() {
Node* list1 = new Node(10);
list1->next = new Node(20);
Node* list2 = new Node(5);
list2->next = new Node(10);
list2->next->next = new Node(20);
if (isSubList(list1, list2)) {
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
return 0;
}
// Java program to search a linked list in another list
class Node {
int data;
Node next;
Node(int x) {
data = x;
next = null;
}
}
class GfG {
static boolean isSubList(Node list1, Node list2) {
Node head2 = list2;
// Starting from each node of list2
while (head2 != null) {
Node head1 = list1;
Node curr = head2;
// Check if list1 is present
// starting from node head2.
while (curr != null && head1 != null
&& head1.data == curr.data) {
curr = curr.next;
head1 = head1.next;
}
// If list1 is completely traversed, it means
// it is present in list2.
if (head1 == null) return true;
// Else, move to the next node of list2.
head2 = head2.next;
}
// If list1 is not present in list2
return false;
}
public static void main(String[] args) {
Node list1 = new Node(10);
list1.next = new Node(20);
Node list2 = new Node(5);
list2.next = new Node(10);
list2.next.next = new Node(20);
if (isSubList(list1, list2)) {
System.out.println("Yes");
} else {
System.out.println("No");
}
}
}
# Python program to search a linked list in another list
class Node:
def __init__(self, x):
self.data = x
self.next = None
def isSubList(list1, list2):
head2 = list2
# Starting from each node of list2
while head2 is not None:
head1 = list1
curr = head2
# Check if list1 is present
# starting from node head2.
while curr is not None and head1 is not None and head1.data == curr.data:
curr = curr.next
head1 = head1.next
# If list1 is completely traversed, it means
# it is present in list2.
if head1 is None:
return True
# Else, move to the next node of list2.
head2 = head2.next
# If list1 is not present in list2
return False
if __name__ == "__main__":
list1 = Node(10)
list1.next = Node(20)
list2 = Node(5)
list2.next = Node(10)
list2.next.next = Node(20)
if isSubList(list1, list2):
print("Yes")
else:
print("No")
// C# program to search a linked list in another list
using System;
class Node {
public int data;
public Node next;
public Node(int x) {
data = x;
next = null;
}
}
class GfG {
static bool isSubList(Node list1, Node list2) {
Node head2 = list2;
// Starting from each node of list2
while (head2 != null) {
Node head1 = list1;
Node curr = head2;
// Check if list1 is present
// starting from node head2.
while (curr != null && head1 != null
&& head1.data == curr.data) {
curr = curr.next;
head1 = head1.next;
}
// If list1 is completely traversed, it means
// it is present in list2.
if (head1 == null) return true;
// Else, move to the next node of list2.
head2 = head2.next;
}
// If list1 is not present in list2
return false;
}
static void Main(string[] args) {
Node list1 = new Node(10);
list1.next = new Node(20);
Node list2 = new Node(5);
list2.next = new Node(10);
list2.next.next = new Node(20);
if (isSubList(list1, list2)) {
Console.WriteLine("Yes");
} else {
Console.WriteLine("No");
}
}
}
// JavaScript program to search a linked list in another list
class Node {
constructor(x) {
this.data = x;
this.next = null;
}
}
function isSubList(list1, list2) {
let head2 = list2;
// Starting from each node of list2
while (head2 !== null) {
let head1 = list1;
let curr = head2;
// Check if list1 is present
// starting from node head2.
while (curr !== null && head1 !== null && head1.data === curr.data) {
curr = curr.next;
head1 = head1.next;
}
// If list1 is completely traversed, it means
// it is present in list2.
if (head1 === null) return true;
// Else, move to the next node of list2.
head2 = head2.next;
}
// If list1 is not present in list2
return false;
}
let list1 = new Node(10);
list1.next = new Node(20);
let list2 = new Node(5);
list2.next = new Node(10);
list2.next.next = new Node(20);
console.log(isSubList(list1, list2) ? "Yes" : "No");
Output
Yes
[Expected Approach] Using KMP Algorithm - O(n + m) time and O(n + m) space
The idea is to convert both linked lists into arrays and then apply the Knuth-Morris-Pratt (KMP) string matching algorithm to efficiently determine if the first list exists as a subsequence within the second list.
Step by step approach:
- Convert both linked lists to arrays (pattern from list1, text from list2)
- Build the LPS (Longest Prefix Suffix) array for the pattern to track partial matches
- Perform the KMP search algorithm on the text and pattern arrays
- Return true if the pattern is found in the text, false otherwise
// C++ program to search a linked list in another list
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node* next;
Node (int x) {
data = x;
next = nullptr;
}
};
// Function to construct lps array.
vector<int> constructLps(vector<int>& pattern) {
int n = pattern.size();
vector<int> lps(n, 0);
for (int i = 1, len = 0; i < n;) {
if (pattern[i] == pattern[len]) {
lps[i++] = ++len;
} else if (len) {
len = lps[len - 1];
} else {
lps[i++] = 0;
}
}
return lps;
}
// Function to perform kmp on text
// and pattern.
int kmp(vector<int>& text, vector<int>& pattern) {
int m = text.size(), n = pattern.size();
vector<int> lps = constructLps(pattern);
for (int i = 0, j = 0; i < m;) {
if (text[i] == pattern[j]) {
i++, j++;
}
// If end of pattern is reached
if (j == n) {
return true;
}
if (i < m && text[i] != pattern[j]) {
if (j != 0) {
j = lps[j - 1];
} else {
i++;
}
}
}
return false;
}
bool isSubList(Node* list1, Node* list2) {
vector<int> pattern, text;
// Convert list1 to pattern array.
Node* head = list1;
while (head != nullptr) {
pattern.push_back(head->data);
head = head->next;
}
// Convert list2 to text array.
head = list2;
while (head != nullptr) {
text.push_back(head->data);
head = head->next;
}
// Apply kmp and check if pattern
// is present in text.
return kmp(text, pattern);
}
int main() {
Node* list1 = new Node(10);
list1->next = new Node(20);
Node* list2 = new Node(5);
list2->next = new Node(10);
list2->next->next = new Node(20);
if (isSubList(list1, list2)) {
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
return 0;
}
// Java program to search a linked list in another list
import java.util.*;
class Node {
int data;
Node next;
Node(int x) {
data = x;
next = null;
}
}
class GfG {
// Function to construct lps array.
static ArrayList<Integer> constructLps(ArrayList<Integer> pattern) {
int n = pattern.size();
ArrayList<Integer> lps = new ArrayList<>(Collections.nCopies(n, 0));
for (int i = 1, len = 0; i < n;) {
if (pattern.get(i).equals(pattern.get(len))) {
lps.set(i++, ++len);
} else if (len > 0) {
len = lps.get(len - 1);
} else {
lps.set(i++, 0);
}
}
return lps;
}
// Function to perform kmp on text
// and pattern.
static boolean kmp(ArrayList<Integer> text, ArrayList<Integer> pattern) {
int m = text.size(), n = pattern.size();
ArrayList<Integer> lps = constructLps(pattern);
for (int i = 0, j = 0; i < m;) {
if (text.get(i).equals(pattern.get(j))) {
i++; j++;
}
// If end of pattern is reached
if (j == n) {
return true;
}
if (i < m && !text.get(i).equals(pattern.get(j))) {
if (j != 0) {
j = lps.get(j - 1);
} else {
i++;
}
}
}
return false;
}
static boolean isSubList(Node list1, Node list2) {
ArrayList<Integer> pattern = new ArrayList<>();
ArrayList<Integer> text = new ArrayList<>();
// Convert list1 to pattern array.
Node head = list1;
while (head != null) {
pattern.add(head.data);
head = head.next;
}
// Convert list2 to text array.
head = list2;
while (head != null) {
text.add(head.data);
head = head.next;
}
// Apply kmp and check if pattern
// is present in text.
return kmp(text, pattern);
}
public static void main(String[] args) {
Node list1 = new Node(10);
list1.next = new Node(20);
Node list2 = new Node(5);
list2.next = new Node(10);
list2.next.next = new Node(20);
if (isSubList(list1, list2)) {
System.out.println("Yes");
} else {
System.out.println("No");
}
}
}
# Python program to search a linked list in another list
class Node:
def __init__(self, x):
self.data = x
self.next = None
# Function to construct lps array.
def constructLps(pattern):
n = len(pattern)
lps = [0] * n
i, length = 1, 0
while i < n:
if pattern[i] == pattern[length]:
length += 1
lps[i] = length
i += 1
elif length:
length = lps[length - 1]
else:
lps[i] = 0
i += 1
return lps
# Function to perform kmp on text
# and pattern.
def kmp(text, pattern):
m, n = len(text), len(pattern)
lps = constructLps(pattern)
i, j = 0, 0
while i < m:
if text[i] == pattern[j]:
i += 1
j += 1
# If end of pattern is reached
if j == n:
return True
if i < m and text[i] != pattern[j]:
if j != 0:
j = lps[j - 1]
else:
i += 1
return False
def isSubList(list1, list2):
pattern, text = [], []
# Convert list1 to pattern array.
head = list1
while head:
pattern.append(head.data)
head = head.next
# Convert list2 to text array.
head = list2
while head:
text.append(head.data)
head = head.next
# Apply kmp and check if pattern
# is present in text.
return kmp(text, pattern)
if __name__ == "__main__":
list1 = Node(10)
list1.next = Node(20)
list2 = Node(5)
list2.next = Node(10)
list2.next.next = Node(20)
if isSubList(list1, list2):
print("Yes")
else:
print("No")
// C# program to search a linked list in another list
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node next;
public Node(int x) {
data = x;
next = null;
}
}
class GfG {
// Function to construct lps array.
static List<int> constructLps(List<int> pattern) {
int n = pattern.Count;
List<int> lps = new List<int>(new int[n]);
for (int i = 1, len = 0; i < n;) {
if (pattern[i] == pattern[len]) {
lps[i++] = ++len;
} else if (len > 0) {
len = lps[len - 1];
} else {
lps[i++] = 0;
}
}
return lps;
}
// Function to perform kmp on text
// and pattern.
static bool kmp(List<int> text, List<int> pattern) {
int m = text.Count, n = pattern.Count;
List<int> lps = constructLps(pattern);
for (int i = 0, j = 0; i < m;) {
if (text[i] == pattern[j]) {
i++; j++;
}
// If end of pattern is reached
if (j == n) {
return true;
}
if (i < m && text[i] != pattern[j]) {
if (j != 0) {
j = lps[j - 1];
} else {
i++;
}
}
}
return false;
}
static bool isSubList(Node list1, Node list2) {
List<int> pattern = new List<int>();
List<int> text = new List<int>();
// Convert list1 to pattern array.
Node head = list1;
while (head != null) {
pattern.Add(head.data);
head = head.next;
}
// Convert list2 to text array.
head = list2;
while (head != null) {
text.Add(head.data);
head = head.next;
}
// Apply kmp and check if pattern
// is present in text.
return kmp(text, pattern);
}
static void Main() {
Node list1 = new Node(10);
list1.next = new Node(20);
Node list2 = new Node(5);
list2.next = new Node(10);
list2.next.next = new Node(20);
if (isSubList(list1, list2)) {
Console.WriteLine("Yes");
} else {
Console.WriteLine("No");
}
}
}
// JavaScript program to search a linked list in another list
class Node {
constructor(x) {
this.data = x;
this.next = null;
}
}
// Function to construct lps array.
function constructLps(pattern) {
let n = pattern.length;
let lps = new Array(n).fill(0);
for (let i = 1, len = 0; i < n;) {
if (pattern[i] === pattern[len]) {
lps[i++] = ++len;
} else if (len) {
len = lps[len - 1];
} else {
lps[i++] = 0;
}
}
return lps;
}
// Function to perform kmp on text
// and pattern.
function kmp(text, pattern) {
let m = text.length, n = pattern.length;
let lps = constructLps(pattern);
for (let i = 0, j = 0; i < m;) {
if (text[i] === pattern[j]) {
i++, j++;
}
// If end of pattern is reached
if (j === n) {
return true;
}
if (i < m && text[i] !== pattern[j]) {
if (j !== 0) {
j = lps[j - 1];
} else {
i++;
}
}
}
return false;
}
function isSubList(list1, list2) {
let pattern = [], text = [];
// Convert list1 to pattern array.
let head = list1;
while (head !== null) {
pattern.push(head.data);
head = head.next;
}
// Convert list2 to text array.
head = list2;
while (head !== null) {
text.push(head.data);
head = head.next;
}
// Apply kmp and check if pattern
// is present in text.
return kmp(text, pattern);
}
let list1 = new Node(10);
list1.next = new Node(20);
let list2 = new Node(5);
list2.next = new Node(10);
list2.next.next = new Node(20);
if (isSubList(list1, list2)) {
console.log("Yes");
} else {
console.log("No");
}
Output
Yes