📜  最小的子数组,在重复时会给出原始数组

📅  最后修改于: 2021-04-22 09:05:45             🧑  作者: Mango

给定N个整数的数组arr [] ,任务是找到大小至少为2的最小子数组brr [] ,以便通过对数组brr []执行重复操作得到原始数组arr [] 。如果找不到这样的子数组,请打印“ -1”

例子:

天真的方法:这个想法是生成长度至少为2的所有可能的子数组,并检查重复这些子数组是否给出原始数组。

时间复杂度: O(N 3 )
辅助空间: O(N)

高效方法:可以通过观察以下事实来优化上述方法生成的子数组brr []必须从原始数组的第一个索引开始才能重复生成arr [] 。因此,仅生成从第一个索引开始并且长度至少为2的那些子数组,并检查重复这些子数组是否给出了原始数组。步骤如下:

  1. 创建一个辅助数组brr []并将原始数组的前两个元素插入其中,因为结果数组的大小必须至少为两个。
  2. 遍历子数组[2,N / 2 + 1]的可能长度,并检查重复时长度为i的brr []数组是否给出原始数组arr []
  3. 如果是,则打印此子数组并中断循环。
  4. 否则,将当前元素插入子数组并再次检查。
  5. 重复上述步骤,直到检查了所有子阵列。
  6. 如果找不到数组brr [],则打印“ -1”。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
#include 
using namespace std;
 
// Function to print the array
void printArray(vector& 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 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;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to print the array
static void printArray(Vector brr)
{
    for(int it : brr)
    {
        System.out.print(it + " ");
    }
}
 
// Function to find the smallest subarray
static void RepeatingSubarray(int arr[], int N)
{
     
    // Corner Case
    if (N < 2)
    {
        System.out.print("-1");
    }
 
    // Initialize the auxiliary subarray
    Vector brr = new Vector();
 
    // Push the first 2 elements into
    // the subarray brr[]
    brr.add(arr[0]);
    brr.add(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)
        {
            boolean 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.get(K))
                {
                    j++;
                }
                else
                {
                    a = true;
                    break;
                }
            }
 
            // Subarray found
            if (!a && j == N)
            {
                printArray(brr);
                return;
            }
        }
 
        // Add current element into
        // subarray
        brr.add(arr[i]);
    }
 
    // No subarray found
    System.out.print("-1");
    return;
}
 
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 1, 2, 2, 1, 2,
                  2, 1, 2, 2 };
 
    int N = arr.length;
 
    // Function call
    RepeatingSubarray(arr, N);
}
}
 
// This code is contributed by Amit Katiyar


Python3
# Python3 program for the above approach
 
# Function to print the array
def printArray(brr):
 
    for it in brr:
        print(it, end = ' ')
 
# Function to find the smallest subarray
def RepeatingSubarray(arr, N):
 
    # Corner Case
    if (N < 2):
        print("-1")
         
    # Initialize the auxiliary subarray
    brr = []
 
    # Push the first 2 elements into
    # the subarray brr[]
    brr.append(arr[0])
    brr.append(arr[1])
 
    # Iterate over the length of
    # subarray
    for i in range(2, N // 2 + 1):
 
        # If array can be divided into
        # subarray of i equal length
        if (N % i == 0):
            a = False
            n = len(brr)
            j = i
 
            # Check if on repeating the
            # current subarray gives the
            # original array or not
            while (j < N):
                K = j % i
                 
                if (arr[j] == brr[K]):
                    j += 1
                else:
                    a = True
                    break
 
            # Subarray found
            if (not a and j == N):
                printArray(brr)
                return
             
        # Add current element into
        # subarray
        brr.append(arr[i])
     
    # No subarray found
    print("-1")
    return
 
# Driver Code
if __name__ =="__main__":
 
    arr = [ 1, 2, 2, 1, 2,
            2, 1, 2, 2 ]
 
    N = len(arr)
 
    # Function call
    RepeatingSubarray(arr, N)
 
# This code is contributed by chitranayal


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
 
// Function to print the array
static void printArray(List brr)
{
    foreach(int it in brr)
    {
        Console.Write(it + " ");
    }
}
 
// Function to find the smallest subarray
static void RepeatingSubarray(int []arr, int N)
{   
    // Corner Case
    if (N < 2)
    {
        Console.Write("-1");
    }
 
    // Initialize the auxiliary subarray
    List brr = new List();
 
    // Push the first 2 elements into
    // the subarray brr[]
    brr.Add(arr[0]);
    brr.Add(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.Count;
            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.Add(arr[i]);
    }
 
    // No subarray found
    Console.Write("-1");
    return;
}
 
// Driver Code
public static void Main(String[] args)
{
    int []arr = {1, 2, 2, 1,
                 2, 2, 1, 2, 2};
 
    int N = arr.Length;
 
    // Function call
    RepeatingSubarray(arr, N);
}
}
 
// This code is contributed by 29AjayKumar


输出:
1 2 2



时间复杂度: O(N 2 )
辅助空间: O(N)