Find All Occurrences of Subarray in Array
Given two arrays a[] and b[], the task is to find all starting indices of b[] as a subarray in a[].
Examples:
Input: a[] = [2, 3, 0, 3, 0, 3, 0], b[] = [3, 0, 3, 0]
Output: [1, 3]
Explanation: The subarray a[1…4] = b[] and subarray a[3…6] = b[].Input : a[] = [1, 2, 3, 4, 5], b[] = [2, 5, 6]
Output: []
Explanation: No subarray of a[] matches with b[].
Table of Content
[Naive Approach] Comparing All Subarrays – O(n*m) Time and O(1) Space
The idea is to check for all possible indices in a[] as starting index of subarray b[]. For each index, compare the subarray of a[] with b[] using a nested loop. If all the elements match, store the starting index in result. If any element does not match, break and check for next starting index.
// C++ Program to search for subarray by matching
// with every possible subarray
#include <iostream>
#include <vector>
using namespace std;
vector<int> search(vector<int> &a, vector<int> &b) {
int n = a.size(), m = b.size();
vector<int> res;
// Iterate over all possible starting indices
for(int i = 0; i < n - m + 1; i++) {
bool isSame = true;
for(int j = 0; j < m; j++) {
// If any character does not match, break
// and begin from the next starting index
if(a[i + j] != b[j]) {
isSame = false;
break;
}
}
// If all characters are matched, store the
// starting index
if(isSame)
res.push_back(i);
}
return res;
}
int main() {
vector<int> a = {2, 3, 0, 3, 0, 3, 0};
vector<int> b = {3, 0, 3, 0};
vector<int> res = search(a, b);
for(int idx: res)
cout << idx << " ";
}
// Java Program to search for subarray by matching
// with every possible subarray
import java.util.ArrayList;
import java.util.List;
class GfG {
static List<Integer> search(int[] a, int[] b) {
int n = a.length, m = b.length;
List<Integer> res = new ArrayList<>();
// Iterate over all possible starting indices
for (int i = 0; i < n - m + 1; i++) {
boolean isSame = true;
// If any character does not match, break
// and begin from the next starting index
for (int j = 0; j < m; j++) {
if (a[i + j] != b[j]) {
isSame = false;
break;
}
}
// If all characters are matched, store
// the starting index
if (isSame)
res.add(i);
}
return res;
}
public static void main(String[] args) {
int[] a = {2, 3, 0, 3, 0, 3, 0};
int[] b = {3, 0, 3, 0};
List<Integer> res = search(a, b);
for (int idx : res)
System.out.print(idx + " ");
}
}
# Python Program to search for subarray by matching
# with every possible subarray
def search(a, b):
n = len(a)
m = len(b)
res = []
# Iterate over all possible starting indices
for i in range(n - m + 1):
isSame = True
for j in range(m):
# If any character does not match, break
# and begin from the next starting index
if a[i + j] != b[j]:
isSame = False
break
# If all characters are matched, store the starting index
if isSame:
res.append(i)
return res
if __name__ == "__main__":
a = [2, 3, 0, 3, 0, 3, 0]
b = [3, 0, 3, 0]
res = search(a, b)
for idx in res:
print(idx, end=" ")
// C# Program to search for subarray by matching
// with every possible subarray
using System;
using System.Collections.Generic;
class GfG {
static List<int> Search(int[] a, int[] b) {
int n = a.Length, m = b.Length;
List<int> res = new List<int>();
// Iterate over all possible starting indices
for (int i = 0; i < n - m + 1; i++) {
bool isSame = true;
for (int j = 0; j < m; j++) {
// If any character does not match, break
// and begin from the next starting index
if (a[i + j] != b[j]) {
isSame = false;
break;
}
}
// If all characters are matched, store the starting index
if (isSame)
res.Add(i);
}
return res;
}
static void Main() {
int[] a = { 2, 3, 0, 3, 0, 3, 0 };
int[] b = { 3, 0, 3, 0 };
List<int> res = Search(a, b);
foreach (int idx in res) {
Console.Write(idx + " ");
}
}
}
// JavaScript Program to search for subarray by matching
// with every possible subarray
function search(a, b) {
let n = a.length, m = b.length;
let res = [];
// Iterate over all possible starting indices
for (let i = 0; i < n - m + 1; i++) {
let isSame = true;
for (let j = 0; j < m; j++) {
// If any character does not match, break
// and begin from the next starting index
if (a[i + j] !== b[j]) {
isSame = false;
break;
}
}
// If all characters are matched, store the starting index
if (isSame)
res.push(i);
}
return res;
}
// Driver code
let a = [2, 3, 0, 3, 0, 3, 0];
let b = [3, 0, 3, 0];
let res = search(a, b);
for (let idx of res) {
console.log(idx + " ");
}
Output
1 3
Time Complexity: O(n*m), where n and m are the sizes of the arrays a[] and b[], respectively.
Space Complexity: O(1) as we are not using any additional space to store the arrays or any other variables.
[Expected Approach] Using KMP Algorithm – O(n+m) Time and O(m) Space
The idea is to use KMP Algorithm with a[] as the text and b[] as the pattern. So, instead of comparing characters, we can compare numbers of the array to construct the lps[] array and find all occurrences of b[] in a[].
// C++ Program to search for subarray using KMP Algorithm
#include <iostream>
#include <vector>
using namespace std;
void constructLps(vector<int> &pat, vector<int> &lps) {
// len stores the length of longest prefix which
// is also a suffix for the previous index
int len = 0;
// lps[0] is always 0
lps[0] = 0;
int i = 1;
while (i < pat.size()) {
// If numbers match, increment the size of lps
if (pat[i] == pat[len]) {
len++;
lps[i] = len;
i++;
}
// If there is a mismatch
else {
if (len != 0) {
// Update len to the previous lps value
// to avoid reduntant comparisons
len = lps[len - 1];
}
else {
// If no matching prefix found, set lps[i] to 0
lps[i] = 0;
i++;
}
}
}
}
vector<int> search(vector<int> &a, vector<int> &b) {
int n = a.size();
int m = b.size();
vector<int> lps(m);
vector<int> res;
constructLps(b, lps);
// Pointers i and j, for traversing a[] and b[]
int i = 0;
int j = 0;
while (i < n) {
// If elements match, move both pointers forward
if (a[i] == b[j]) {
i++;
j++;
// If all elements of b[] are matched
// store the start index in result
if (j == m) {
res.push_back(i - j);
// Use LPS of previous index to
// skip unnecessary comparisons
j = lps[j - 1];
}
}
// If there is a mismatch
else {
// Use lps value of previous index
// to avoid redundant comparisons
if (j != 0)
j = lps[j - 1];
else
i++;
}
}
return res;
}
int main() {
vector<int> a = {2, 3, 0, 3, 0, 3, 0};
vector<int> b = {3, 0, 3, 0};
vector<int> res = search(a, b);
for(int idx: res)
cout << idx << " ";
}
// Java Program to search for subarray using KMP Algorithm
import java.util.ArrayList;
import java.util.List;
class GfG {
// Function to construct LPS array
static void constructLps(int[] pat, int[] lps) {
// len stores the length of longest prefix which
// is also a suffix for the previous index
int len = 0;
// lps[0] is always 0
lps[0] = 0;
int i = 1;
while (i < pat.length) {
// If numbers match, increment the size of lps
if (pat[i] == pat[len]) {
len++;
lps[i] = len;
i++;
}
// If there is a mismatch
else {
if (len != 0) {
// Update len to the previous lps value
// to avoid redundant comparisons
len = lps[len - 1];
} else {
// If no matching prefix found, set lps[i] to 0
lps[i] = 0;
i++;
}
}
}
}
// Function to search for the subarray using KMP algorithm
static List<Integer> search(int[] a, int[] b) {
int n = a.length;
int m = b.length;
int[] lps = new int[m];
List<Integer> res = new ArrayList<>();
constructLps(b, lps);
// Pointers i and j, for traversing a[] and b[]
int i = 0;
int j = 0;
while (i < n) {
// If elements match, move both pointers forward
if (a[i] == b[j]) {
i++;
j++;
// If all elements of b[] are matched
// store the start index in result
if (j == m) {
res.add(i - j);
// Use LPS of previous index to
// skip unnecessary comparisons
j = lps[j - 1];
}
}
// If there is a mismatch
else {
// Use lps value of previous index
// to avoid redundant comparisons
if (j != 0)
j = lps[j - 1];
else
i++;
}
}
return res;
}
public static void main(String[] args) {
int[] a = {2, 3, 0, 3, 0, 3, 0};
int[] b = {3, 0, 3, 0};
List<Integer> res = search(a, b);
for (int idx : res)
System.out.print(idx + " ");
}
}
# Python Program to search for subarray using KMP Algorithm
def constructLps(pat, lps):
# len stores the length of longest prefix which
# is also a suffix for the previous index
length = 0
# lps[0] is always 0
lps[0] = 0
i = 1
while i < len(pat):
# If numbers match, increment the size of lps
if pat[i] == pat[length]:
length += 1
lps[i] = length
i += 1
# If there is a mismatch
else:
if length != 0:
# Update length to the previous lps value
# to avoid redundant comparisons
length = lps[length - 1]
else:
# If no matching prefix found, set lps[i] to 0
lps[i] = 0
i += 1
def search(a, b):
n = len(a)
m = len(b)
lps = [0] * m
res = []
constructLps(b, lps)
# Pointers i and j, for traversing a[] and b[]
i = 0
j = 0
while i < n:
# If elements match, move both pointers forward
if a[i] == b[j]:
i += 1
j += 1
# If all elements of b[] are matched
# store the start index in result
if j == m:
res.append(i - j)
# Use LPS of previous index to
# skip unnecessary comparisons
j = lps[j - 1]
else:
# If there is a mismatch
# Use lps value of previous index
# to avoid redundant comparisons
if j != 0:
j = lps[j - 1]
else:
i += 1
return res
if __name__ == "__main__":
a = [2, 3, 0, 3, 0, 3, 0]
b = [3, 0, 3, 0]
res = search(a, b)
for idx in res:
print(idx, end=" ")
// C# Program to search for subarray using KMP Algorithm
using System;
using System.Collections.Generic;
class GfG {
// Function to construct the LPS array (Longest Prefix Suffix)
static void ConstructLps(int[] pat, int[] lps) {
// len stores the length of the longest prefix which
// is also a suffix for the previous index
int len = 0;
// lps[0] is always 0
lps[0] = 0;
int i = 1;
while (i < pat.Length) {
// If numbers match, increment the size of lps
if (pat[i] == pat[len]) {
len++;
lps[i] = len;
i++;
}
// If there is a mismatch
else {
if (len != 0) {
// Update len to the previous lps value
// to avoid redundant comparisons
len = lps[len - 1];
}
else {
// If no matching prefix found, set lps[i] to 0
lps[i] = 0;
i++;
}
}
}
}
// Function to search for the subarray
static List<int> Search(int[] a, int[] b) {
int n = a.Length;
int m = b.Length;
int[] lps = new int[m];
List<int> res = new List<int>();
ConstructLps(b, lps);
// Pointers i and j, for traversing a[] and b[]
int i = 0;
int j = 0;
while (i < n) {
// If elements match, move both pointers forward
if (a[i] == b[j]) {
i++;
j++;
// If all elements of b[] are matched
// store the start index in result
if (j == m) {
res.Add(i - j);
// Use LPS of previous index to
// skip unnecessary comparisons
j = lps[j - 1];
}
}
// If there is a mismatch
else {
// Use lps value of previous index
// to avoid redundant comparisons
if (j != 0)
j = lps[j - 1];
else
i++;
}
}
// Convert the List<int> to an int[] before returning
return res;
}
static void Main() {
int[] a = { 2, 3, 0, 3, 0, 3, 0 };
int[] b = { 3, 0, 3, 0 };
List<int> res = Search(a, b);
foreach (int idx in res) {
Console.Write(idx + " ");
}
}
}
// JavaScript Program to search for subarray using KMP Algorithm
function constructLps(pat, lps) {
// len stores the length of longest prefix which
// is also a suffix for the previous index
let len = 0;
// lps[0] is always 0
lps[0] = 0;
let i = 1;
while (i < pat.length) {
// If numbers match, increment the size of lps
if (pat[i] === pat[len]) {
len++;
lps[i] = len;
i++;
}
// If there is a mismatch
else {
if (len !== 0) {
// Update len to the previous lps value
// to avoid redundant comparisons
len = lps[len - 1];
}
else {
// If no matching prefix found, set lps[i] to 0
lps[i] = 0;
i++;
}
}
}
}
function search(a, b) {
let n = a.length;
let m = b.length;
let lps = new Array(m);
let res = [];
constructLps(b, lps);
// Pointers i and j, for traversing a[] and b[]
let i = 0;
let j = 0;
while (i < n) {
// If elements match, move both pointers forward
if (a[i] === b[j]) {
i++;
j++;
// If all elements of b[] are matched
// store the start index in result
if (j === m) {
res.push(i - j);
// Use LPS of previous index to
// skip unnecessary comparisons
j = lps[j - 1];
}
}
// If there is a mismatch
else {
// Use lps value of previous index
// to avoid redundant comparisons
if (j !== 0)
j = lps[j - 1];
else
i++;
}
}
return res;
}
// Driver Code
let a = [2, 3, 0, 3, 0, 3, 0];
let b = [3, 0, 3, 0];
let res = search(a, b);
for (let idx of res) {
console.log(idx + " ");
}
Output
1 3
Time Complexity: O(n+m), where n and m are the sizes of the arrays a[] and b[], respectively.
Auxiliary Space: O(m), for lps[] array.
Related Topic: Subarrays, Subsequences, and Subsets in Array