📌  相关文章
📜  最小子数组,其元素的频率大于其他元素的频率

📅  最后修改于: 2021-05-14 01:27:55             🧑  作者: Mango

给定一个正整数数组arr ,任务是找到长度大于1的最小长度子数组,该子数组中一个元素的出现次数比其他任何元素都要多。

例子:

天真的方法:解决问题的天真的方法可以是找到所有具有满足给定条件的元素的子数组,然后找到所有这些子数组中的最小值。

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

高效方法:可以减少问题,以发现如果子数组中两次出现任何元素,那么这可能是一个可能的答案。因为此类子数组的最小长度可以是两个相同元素之间的最小距离

这个想法是使用一个额外的数组来维护给定数组中元素的最后一次出现。然后找到元素的最后一次出现与当前位置之间的距离,并找到所有此类长度中的最小值。

下面是上述方法的实现。

C++
// C++ program for the above approach
#include  
using namespace std;
  
// Function to find subarray
void FindSubarray(int arr[], int n)
{
    // If the array has only one element,
    // then there is no answer.
    if (n == 1) {
        cout << "No such subarray!"
             << endl;
    }
  
    // Array to store the last occurrences
    // of the elements of the array.
    int vis[n + 1];
    memset(vis, -1, sizeof(vis));
    vis[arr[0]] = 0;
  
    // To maintain the length
    int len = INT_MAX, flag = 0;
  
    // Variables to store
    // start and end indices
    int start, end;
  
    for (int i = 1; i < n; i++) {
        int t = arr[i];
  
        // Check if element is occurring
        // for the second time in the array
        if (vis[t] != -1) {
            // Find distance between last
            // and current index
            // of the element.
            int distance = i - vis[t] + 1;
  
            // If the current distance
            // is less then len
            // update len and
            // set 'start' and 'end'
            if (distance < len) {
                len = distance;
                start = vis[t];
                end = i;
            }
            flag = 1;
        }
  
        // Set the last occurrence
        // of current element to be 'i'.
        vis[t] = i;
    }
  
    // If flag is equal to 0,
    // it means there is no answer.
    if (flag == 0)
        cout << "No such subarray!"
             << endl;
    else {
        for (int i = start; i <= end; i++)
            cout << arr[i] << " ";
    }
}
  
// Driver Code
int main()
{
    int arr[] = { 2, 3, 2, 4, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    FindSubarray(arr, n);
  
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
  
class GFG{
      
// Function to find subarray 
public static void FindSubarray(int[] arr, 
                                int n) 
{ 
      
    // If the array has only one element, 
    // then there is no answer. 
    if (n == 1)
    { 
        System.out.println("No such subarray!");
    } 
  
    // Array to store the last occurrences 
    // of the elements of the array. 
    int[] vis = new int[n + 1]; 
    Arrays.fill(vis, -1);
    vis[arr[0]] = 0; 
  
    // To maintain the length 
    int len = Integer.MAX_VALUE, flag = 0; 
  
    // Variables to store 
    // start and end indices 
    int start = 0, end = 0; 
  
    for(int i = 1; i < n; i++)
    { 
        int t = arr[i]; 
  
        // Check if element is occurring 
        // for the second time in the array 
        if (vis[t] != -1)
        {
              
            // Find distance between last 
            // and current index 
            // of the element. 
            int distance = i - vis[t] + 1; 
  
            // If the current distance 
            // is less then len 
            // update len and 
            // set 'start' and 'end' 
            if (distance < len)
            { 
                len = distance; 
                start = vis[t]; 
                end = i; 
            } 
            flag = 1; 
        } 
  
        // Set the last occurrence 
        // of current element to be 'i'. 
        vis[t] = i; 
    } 
      
    // If flag is equal to 0, 
    // it means there is no answer. 
    if (flag == 0) 
        System.out.println("No such subarray!");
          
    else
    { 
        for(int i = start; i <= end; i++) 
            System.out.print(arr[i] + " ");
    } 
}
  
// Driver code
public static void main(String[] args)
{
    int arr[] = { 2, 3, 2, 4, 5 }; 
    int n = arr.length; 
  
    FindSubarray(arr, n); 
}
}
  
// This code is contributed by divyeshrabadiya07


Python3
# Python3 program for the above approach
import sys
  
# Function to find subarray
def FindSubarray(arr, n):
  
    # If the array has only one element,
    # then there is no answer.
    if (n == 1):
        print("No such subarray!")
  
    # Array to store the last occurrences
    # of the elements of the array.
    vis = [-1] * (n + 1)
    vis[arr[0]] = 0
  
    # To maintain the length
    length = sys.maxsize
    flag = 0
      
    for i in range(1, n):
        t = arr[i]
  
        # Check if element is occurring
        # for the second time in the array
        if (vis[t] != -1):
              
            # Find distance between last
            # and current index
            # of the element.
            distance = i - vis[t] + 1
  
            # If the current distance
            # is less then len
            # update len and
            # set 'start' and 'end'
            if (distance < length):
                length = distance
                start = vis[t]
                end = i
              
            flag = 1
  
        # Set the last occurrence
        # of current element to be 'i'.
        vis[t] = i
  
    # If flag is equal to 0,
    # it means there is no answer.
    if (flag == 0):
        print("No such subarray!")
    else:
        for i in range(start, end + 1):
            print(arr[i], end = " ")
  
# Driver Code
if __name__ == "__main__":
  
    arr = [ 2, 3, 2, 4, 5 ]
    n = len(arr)
  
    FindSubarray(arr, n)
  
# This code is contributed by chitranayal


C#
// C# program for the above approach
using System;
class GFG{
      
// Function to find subarray 
public static void FindSubarray(int[] arr, 
                                int n) 
{ 
      
    // If the array has only one element, 
    // then there is no answer. 
    if (n == 1)
    { 
        Console.WriteLine("No such subarray!");
    } 
  
    // Array to store the last occurrences 
    // of the elements of the array. 
    int[] vis = new int[n + 1]; 
    for(int i = 0; i < n + 1; i++)
        vis[i] = -1;
    vis[arr[0]] = 0; 
  
    // To maintain the length 
    int len = int.MaxValue, flag = 0; 
  
    // Variables to store 
    // start and end indices 
    int start = 0, end = 0; 
  
    for(int i = 1; i < n; i++)
    { 
        int t = arr[i]; 
  
        // Check if element is occurring 
        // for the second time in the array 
        if (vis[t] != -1)
        {
              
            // Find distance between last 
            // and current index 
            // of the element. 
            int distance = i - vis[t] + 1; 
  
            // If the current distance 
            // is less then len 
            // update len and 
            // set 'start' and 'end' 
            if (distance < len)
            { 
                len = distance; 
                start = vis[t]; 
                end = i; 
            } 
            flag = 1; 
        } 
  
        // Set the last occurrence 
        // of current element to be 'i'. 
        vis[t] = i; 
    } 
      
    // If flag is equal to 0, 
    // it means there is no answer. 
    if (flag == 0) 
        Console.WriteLine("No such subarray!");
          
    else
    { 
        for(int i = start; i <= end; i++) 
            Console.Write(arr[i] + " ");
    } 
}
  
// Driver code
public static void Main(String[] args)
{
    int []arr = { 2, 3, 2, 4, 5 }; 
    int n = arr.Length; 
  
    FindSubarray(arr, n); 
}
}
  
// This code is contributed by sapnasingh4991


输出:
2 3 2

时间复杂度: O(N) ,其中n是数组的长度。

辅助空间: O(N)