Given an array arr[] of N integers, the task is to find the smallest subarray **brr[] **of size at least 2 such that by performing repeating operation on the array **brr[] **gives the original array arr[]. Print “-1” if it is not possible to find such subarray.
A repeating operation on an array is to append all the current element of the array to the same array again.
For Example, if an array arr[] = {1, 2} then on repeating operation array becomes **{1, 2, 1, 2}**.
Examples:
Input:_ arr[] = {1, 2, 3, 3, 1, 2, 3, 3}_
Output:_ {1, 2, 3, 3}_
Explanation:
{1, 2, 3, 3} is the smallest subarray which when repeated 2 times gives the original array {1, 2, 3, 3, 1, 2, 3, 3}
Input:_ arr[] = {1, 1, 6, 1, 1, 7}_
Output:_ -1_
Explanation:
There doesn’t exist any subarray.
Naive Approach: The idea is to generate all possible subarrays of length at least 2 and check whether repeating those subarrays gives the original array or not.
Time Complexity:_ O(N3)_
Auxiliary Space:_ O(N)_
Efficient Approach: The above approach can be optimized by observing the fact that the resultant subarray **brr[] **must start from the 1st index of the original array to generate **arr[] **on repeating. Therefore, generate only those subarrays which start from the 1st index and have a length of at least 2 and check whether repeating those subarrays gives the original array or not. Below are the steps:
Below is the implementation of the above approach:
// C++ program for the above approach
#include <iostream>
#include <vector>
**using**
**namespace**
std;
// Function to print the array
**void**
printArray(vector<``**int**``>& brr)
{
**for**
(``**auto**``& it : brr) {
cout << it <<
' '``;
}
}
// Function to find the smallest subarray
**void**
RepeatingSubarray(``**int**
arr[],
**int**
N)
{
// Corner Case
**if**
(N < 2) {
cout <<
"-1"``;
}
// Initialize the auxiliary subarray
vector<``**int**``> brr;
// Push the first 2 elements into
// the subarray brr[]
brr.push_back(arr[0]);
brr.push_back(arr[1]);
// Iterate over the length of
// subarray
**for**
(``**int**
i = 2; i < N / 2 + 1; i++) {
// If array can be divided into
// subarray of i equal length
**if**
(N % i == 0) {
**bool**
a =
**false**``;
**int**
n = brr.size();
**int**
j = i;
// Check if on repeating the
// current subarray gives the
// original array or not
**while**
(j < N) {
**int**
K = j % i;
**if**
(arr[j] == brr[K]) {
j++;
}
**else**
{
a =
**true**``;
**break**``;
}
}
// Subarray found
**if**
(!a && j == N) {
printArray(brr);
**return**``;
}
}
// Add current element into
// subarray
brr.push_back(arr[i]);
}
// No subarray found
cout <<
"-1"``;
**return**``;
}
// Driver Code
**int**
main()
{
**int**
arr[] = { 1, 2, 2, 1, 2,
2, 1, 2, 2 };
**int**
N =
**sizeof**``(arr) /
**sizeof**``(arr[0]);
// Function call
RepeatingSubarray(arr, N);
**return**
0;
}
Output:
1 2 2
Time Complexity:_ O(N2)_
Auxiliary Space:_ O(N)_
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.
#arrays #greedy #mathematical #subarray