Given two arrays A and B, the task is to find the starting index for every occurrence of array B in array A using Z-Algorithm.
Examples:
Input: A = {1, 2, 3, 2, 3}, B = {2, 3}
Output: 1 3
Explanation:
In array A, array B occurs at index 1 and index 3. Thus the answer is {1, 3}.
Input: A = {1, 1, 1, 1, 1}, B = {1}
Output: 0 1 2 3 4
In array A, array B occur at the index {0, 1, 2, 3, 4}.
In Z-Algorithm, we construct a Z-Array.
What is Z-Array?
For a arr[0..n-1], Z array is an array, of the same length as the string array arr, where each element Z[i] of Z array stores length of the longest substring starting from arr[i] which is also a prefix of arr[0..n-1]. The first entry of Z array is meaningless as complete array is always prefix of itself.
For example: For a given array arr[] = { 1, 2, 3, 0, 1, 2, 3, 5}

Approach:
- Merge array B and array A with a separator in between into a new array C. Here separator can be any special character.
- Create Z-array using array C.
- Iterate over the Z-array and print all those indices whose value is greater than or equal to the length of the array B.
Below is the implementation of the above approach.
C++
#include<bits/stdc++.h>
using namespace std;
vector< int > zArray(vector< int > arr)
{
int n = arr.size();
vector< int > z(n);
int r = 0, l = 0;
for ( int k = 1; k < n; k++) {
if (k > r) {
r = l = k;
while (r < n
&& arr[r] == arr[r - l])
r++;
z[k] = r - l;
r--;
}
else {
int k1 = k - l;
if (z[k1] < r - k + 1)
z[k] = z[k1];
else {
l = k;
while (r < n
&& arr[r] == arr[r - l])
r++;
z[k] = r - l;
r--;
}
}
}
return z;
}
vector< int > mergeArray(vector< int > A, vector< int > B)
{
int n = A.size();
int m = B.size();
vector< int > z;
vector< int > c(n + m + 1);
for ( int i = 0; i < m; i++)
c[i] = B[i];
c[m] = INT_MAX;
for ( int i = 0; i < n; i++)
c[m + i + 1] = A[i];
z = zArray(c);
return z;
}
void findZArray(vector< int >A,vector< int >B, int n)
{
int flag = 0;
vector< int > z;
z = mergeArray(A, B);
for ( int i = 0; i < z.size(); i++) {
if (z[i] == n) {
cout << (i - n - 1) << " " ;
flag = 1;
}
}
if (flag == 0) {
cout << ( "Not Found" );
}
}
int main()
{
vector< int >A{ 1, 2, 3, 2, 3, 2 };
vector< int >B{ 2, 3 };
int n = B.size();
findZArray(A, B, n);
}
|
Java
import java.io.*;
import java.util.*;
class GfG {
private static int [] zArray( int arr[])
{
int z[];
int n = arr.length;
z = new int [n];
int r = 0 , l = 0 ;
for ( int k = 1 ; k < n; k++) {
if (k > r) {
r = l = k;
while (r < n
&& arr[r] == arr[r - l])
r++;
z[k] = r - l;
r--;
}
else {
int k1 = k - l;
if (z[k1] < r - k + 1 )
z[k] = z[k1];
else {
l = k;
while (r < n
&& arr[r] == arr[r - l])
r++;
z[k] = r - l;
r--;
}
}
}
return z;
}
private static int [] mergeArray( int A[],
int B[])
{
int n = A.length;
int m = B.length;
int z[];
int c[] = new int [n + m + 1 ];
for ( int i = 0 ; i < m; i++)
c[i] = B[i];
c[m] = Integer.MAX_VALUE;
for ( int i = 0 ; i < n; i++)
c[m + i + 1 ] = A[i];
z = zArray(c);
return z;
}
private static void findZArray( int A[], int B[], int n)
{
int flag = 0 ;
int z[];
z = mergeArray(A, B);
for ( int i = 0 ; i < z.length; i++) {
if (z[i] == n) {
System.out.print((i - n - 1 )
+ " " );
flag = 1 ;
}
}
if (flag == 0 ) {
System.out.println( "Not Found" );
}
}
public static void main(String args[])
{
int A[] = { 1 , 2 , 3 , 2 , 3 , 2 };
int B[] = { 2 , 3 };
int n = B.length;
findZArray(A, B, n);
}
}
|
Python3
import sys;
def zArray(arr) :
n = len (arr);
z = [ 0 ] * n;
r = 0 ;
l = 0 ;
for k in range ( 1 , n) :
if (k > r) :
r = l = k;
while (r < n and arr[r] = = arr[r - l]) :
r + = 1 ;
z[k] = r - l;
r - = 1 ;
else :
k1 = k - l;
if (z[k1] < r - k + 1 ) :
z[k] = z[k1];
else :
l = k;
while (r < n and arr[r] = = arr[r - l]) :
r + = 1 ;
z[k] = r - l;
r - = 1 ;
return z;
def mergeArray(A,B) :
n = len (A);
m = len (B);
c = [ 0 ] * (n + m + 1 );
for i in range (m) :
c[i] = B[i];
c[m] = sys.maxsize;
for i in range (n) :
c[m + i + 1 ] = A[i];
z = zArray(c);
return z;
def findZArray( A,B, n) :
flag = 0 ;
z = mergeArray(A, B);
for i in range ( len (z)) :
if (z[i] = = n) :
print (i - n - 1 , end = " " );
flag = 1 ;
if (flag = = 0 ) :
print ( "Not Found" );
if __name__ = = "__main__" :
A = [ 1 , 2 , 3 , 2 , 3 , 2 ];
B = [ 2 , 3 ];
n = len (B);
findZArray(A, B, n);
|
C#
using System;
class GfG
{
private static int [] zArray( int []arr)
{
int []z;
int n = arr.Length;
z = new int [n];
int r = 0, l = 0;
for ( int k = 1; k < n; k++)
{
if (k > r)
{
r = l = k;
while (r < n
&& arr[r] == arr[r - l])
r++;
z[k] = r - l;
r--;
}
else
{
int k1 = k - l;
if (z[k1] < r - k + 1)
z[k] = z[k1];
else
{
l = k;
while (r < n
&& arr[r] == arr[r - l])
r++;
z[k] = r - l;
r--;
}
}
}
return z;
}
private static int [] mergeArray( int []A,
int []B)
{
int n = A.Length;
int m = B.Length;
int []z;
int []c = new int [n + m + 1];
for ( int i = 0; i < m; i++)
c[i] = B[i];
c[m] = int .MaxValue;
for ( int i = 0; i < n; i++)
c[m + i + 1] = A[i];
z = zArray(c);
return z;
}
private static void findZArray( int []A, int []B, int n)
{
int flag = 0;
int []z;
z = mergeArray(A, B);
for ( int i = 0; i < z.Length; i++)
{
if (z[i] == n)
{
Console.Write((i - n - 1)
+ " " );
flag = 1;
}
}
if (flag == 0)
{
Console.WriteLine( "Not Found" );
}
}
public static void Main()
{
int []A = { 1, 2, 3, 2, 3, 2 };
int []B = { 2, 3 };
int n = B.Length;
findZArray(A, B, n);
}
}
|
Javascript
<script>
function zArray(arr) {
let n = arr.length;
let z = new Array(n);
let r = 0, l = 0;
for (let k = 1; k < n; k++) {
if (k > r) {
r = l = k;
while (r < n
&& arr[r] == arr[r - l])
r++;
z[k] = r - l;
r--;
}
else {
let k1 = k - l;
if (z[k1] < r - k + 1)
z[k] = z[k1];
else {
l = k;
while (r < n
&& arr[r] == arr[r - l])
r++;
z[k] = r - l;
r--;
}
}
}
return z;
}
function mergeArray(A, B) {
let n = A.length;
let m = B.length;
let z = new Array();
let c = new Array(n + m + 1);
for (let i = 0; i < m; i++)
c[i] = B[i];
c[m] = Number.MAX_SAFE_INTEGER;
for (let i = 0; i < n; i++)
c[m + i + 1] = A[i];
z = zArray(c);
return z;
}
function findZArray(A, B, n) {
let flag = 0;
let z = [];
z = mergeArray(A, B);
for (let i = 0; i < z.length; i++) {
if (z[i] == n) {
document.write((i - n - 1) + " " );
flag = 1;
}
}
if (flag == 0) {
document.write( "Not Found" );
}
}
let A = [1, 2, 3, 2, 3, 2];
let B = [2, 3];
let n = B.length;
findZArray(A, B, n);
</script>
|
Time Complexity: O(N + M).
Auxiliary Space: O(N + M), where N and M are the sizes of the given vectors A and B respectively.