Open In App

Find All Occurrences of Subarray in Array

Last Updated : 26 Nov, 2024
Comments
Improve
Suggest changes
22 Likes
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 Python C# JavaScript

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 Python C# JavaScript

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
Article Tags :
Practice Tags :

Similar Reads