Open In App

Find All Occurrences of Subarray in Array

Last Updated : 26 Nov, 2024
Suggest changes
Share
Like Article
Like
Report

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[].

[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++
// 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
// 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
# 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#
// 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
// 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++
// 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
// 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
# 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#
// 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
// 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


Next Article

Similar Reads

Article Tags :