📌  相关文章
📜  所有出现频率最高的元素的最小子数组

📅  最后修改于: 2021-10-28 01:27:20             🧑  作者: Mango

给定一个数组 A。让 x 成为数组中的一个元素。 x 具有阵列中的最大频率。找到数组的最小子段,其中 x 作为最大频率元素。
例子:

Input :  arr[] = {4, 1, 1, 2, 2, 1, 3, 3} 
Output :   1, 1, 2, 2, 1
The most frequent element is 1. The smallest
subarray that has all occurrences of it is
1 1 2 2 1

Input :  A[] = {1, 2, 2, 3, 1}
Output : 2, 2
Note that there are two elements that appear
two times, 1 and 2. The smallest window for
1 is whole array and smallest window for 2 is
{2, 2}. Since window for 2 is smaller, this is
our output.

方法:观察,如果 X 是我们子段的最大重复元素,那么太阳段应该看起来像这样 [X, ….., X],因为如果子段以另一个元素结束或开始,我们可以删除它,这不会改变我们的回答。
为了解决这个问题,让我们为数组中的每个不同元素存储三个值,元素第一次出现的索引和元素最后一次出现的索引以及元素的频率。并且在最大重复元素的每一步最小化我们的子段的大小。

C++
// C++ implementation to find smallest
// subarray with all occurrences of
// a most frequent element
#include 
using namespace std;
 
void smallestSubsegment(int a[], int n)
{
    // To store left most occurrence of elements
    unordered_map left;
 
    // To store counts of elements
    unordered_map count;
 
    // To store maximum frequency
    int mx = 0;
 
    // To store length and starting index of
    // smallest result window
    int mn, strindex;
 
    for (int i = 0; i < n; i++) {
 
        int x = a[i];
 
        // First occurrence of an element,
        // store the index
        if (count[x] == 0) {
            left[x] = i;
            count[x] = 1;
        }
 
        // increase the frequency of elements
        else
            count[x]++;
 
        // Find maximum repeated element and
        // store its last occurrence and first
        // occurrence
        if (count[x] > mx) {
            mx = count[x];
            mn = i - left[x] + 1; // length of subsegment
            strindex = left[x];
        }
 
        // select subsegment of smallest size
        else if (count[x] == mx && i - left[x] + 1 < mn) {
            mn = i - left[x] + 1;
            strindex = left[x];
        }
    }
 
    // Print the subsegment with all occurrences of
    // a most frequent element
    for (int i = strindex; i < strindex + mn; i++)
        cout << a[i] << " ";
}
 
// Driver code
int main()
{
    int A[] = { 1, 2, 2, 2, 1 };
    int n = sizeof(A) / sizeof(A[0]);
    smallestSubsegment(A, n);
    return 0;
}


Java
// Java implementation to find smallest
// subarray with all occurrences of
// a most frequent element
import java.io.*;
import java.util.*;
class GfG {
     
    static void smallestSubsegment(int a[], int n)
    {
        // To store left most occurrence of elements
        HashMap left= new HashMap();
     
        // To store counts of elements
        HashMap count= new HashMap();
     
        // To store maximum frequency
        int mx = 0;
     
        // To store length and starting index of
        // smallest result window
        int mn = -1, strindex = -1;
     
        for (int i = 0; i < n; i++)
        {
     
            int x = a[i];
     
            // First occurrence of an element,
            // store the index
            if (count.get(x) == null)
            {
                left.put(x, i) ;
                count.put(x, 1);
            }
     
            // increase the frequency of elements
            else
                count.put(x, count.get(x) + 1);
     
            // Find maximum repeated element and
            // store its last occurrence and first
            // occurrence
            if (count.get(x) > mx)
            {
                mx = count.get(x);
                 
                // length of subsegment
                mn = i - left.get(x) + 1;
                strindex = left.get(x);
            }
     
            // select subsegment of smallest size
            else if ((count.get(x) == mx) &&
                    (i - left.get(x) + 1 < mn))
            {
                mn = i - left.get(x) + 1;
                strindex = left.get(x);
            }
        }
     
        // Print the subsegment with all occurrences of
        // a most frequent element
        for (int i = strindex; i < strindex + mn; i++)
            System.out.print(a[i] + " ");
    }
     
    // Driver program
    public static void main (String[] args)
    {
        int A[] = { 1, 2, 2, 2, 1 };
        int n = A.length;
        smallestSubsegment(A, n);
    }
}
 
// This code is contributed by Gitanjali.


Python3
# Python3 implementation to find smallest
# subarray with all occurrences of
# a most frequent element
def smallestSubsegment(a, n):
     
    # To store left most occurrence of elements
    left = dict()
 
    # To store counts of elements
    count = dict()
 
    # To store maximum frequency
    mx = 0
 
    # To store length and starting index of
    # smallest result window
    mn, strindex = 0, 0
 
    for i in range(n):
 
        x = a[i]
 
        # First occurrence of an element,
        # store the index
        if (x not in count.keys()):
            left[x] = i
            count[x] = 1
 
        # increase the frequency of elements
        else:
            count[x] += 1
 
        # Find maximum repeated element and
        # store its last occurrence and first
        # occurrence
        if (count[x] > mx):
            mx = count[x]
            mn = i - left[x] + 1 # length of subsegment
            strindex = left[x]
 
        # select subsegment of smallest size
        elif (count[x] == mx and
              i - left[x] + 1 < mn):
            mn = i - left[x] + 1
            strindex = left[x]
             
    # Print the subsegment with all occurrences of
    # a most frequent element
    for i in range(strindex, strindex + mn):
        print(a[i], end = " ")
 
# Driver code
A = [1, 2, 2, 2, 1]
n = len(A)
smallestSubsegment(A, n)
 
# This code is contributed by Mohit Kumar


C#
// C# implementation to find smallest
// subarray with all occurrences of
// a most frequent element
using System;
using System.Collections.Generic;
 
class GfG
{
     
    static void smallestSubsegment(int []a, int n)
    {
        // To store left most occurrence of elements
        Dictionary left = new Dictionary();
     
        // To store counts of elements
        Dictionary count = new Dictionary();
     
        // To store maximum frequency
        int mx = 0;
     
        // To store length and starting index of
        // smallest result window
        int mn = -1, strindex = -1;
     
        for (int i = 0; i < n; i++)
        {
     
            int x = a[i];
     
            // First occurrence of an element,
            // store the index
            if (!count.ContainsKey(x))
            {
                left.Add(x, i) ;
                count.Add(x, 1);
            }
     
            // increase the frequency of elements
            else
                count[x] = count[x] + 1;
     
            // Find maximum repeated element and
            // store its last occurrence and first
            // occurrence
            if (count[x] > mx)
            {
                mx = count[x];
                 
                // length of subsegment
                mn = i - left[x] + 1;
                strindex = left[x];
            }
     
            // select subsegment of smallest size
            else if ((count[x] == mx) &&
                    (i - left[x] + 1 < mn))
            {
                mn = i - left[x] + 1;
                strindex = left[x];
            }
        }
     
        // Print the subsegment with all occurrences of
        // a most frequent element
        for (int i = strindex; i < strindex + mn; i++)
            Console.Write(a[i] + " ");
    }
     
    // Driver code
    public static void Main (String[] args)
    {
        int []A = { 1, 2, 2, 2, 1 };
        int n = A.Length;
        smallestSubsegment(A, n);
    }
}
 
// This code is contributed by PrinciRaj1992


Javascript


输出:

2 2 2 

时间复杂度: O(n)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程