📌  相关文章
📜  在少于O(n)的时间内找到有限范围阵列中每个元素的频率

📅  最后修改于: 2021-04-26 05:40:00             🧑  作者: Mango

给定一个带正整数的排序数组,该数组中每个元素的出现次数计数。假设数组中的所有元素都小于某个常数M。
这样做无需遍历整个数组。即,预期的时间复杂度小于O(n)。
例子:

Input: arr[] = [1, 1, 1, 2, 3, 3, 5,
               5, 8, 8, 8, 9, 9, 10] 
Output:
Element 1 occurs 3 times
Element 2 occurs 1 times
Element 3 occurs 2 times
Element 5 occurs 2 times
Element 8 occurs 3 times
Element 9 occurs 2 times
Element 10 occurs 1 times

Input: arr[] = [2, 2, 6, 6, 7, 7, 7, 11] 
Output:
Element 2 occurs 2 times
Element 6 occurs 2 times
Element 7 occurs 3 times
Element 11 occurs 1 times

方法1此方法使用线性搜索技术来解决以下问题。

  • 方法:想法是遍历输入数组,并针对该数组的每个不同元素,将其频率存储在HashMap中,最后打印HashMap。
  • 算法:
    1. 创建一个HashMap将频率映射到元素,即存储元素-频率对。
    2. 从头到尾遍历数组。
    3. 对于数组中的每个元素,更新频率,即hm [array [i]] ++
    4. 遍历HashMap并打印元素频率对。
  • 执行:
C++
// C++ program to count number of occurrences of
// each element in the array #include 
#include 
using namespace std;
 
// It prints number of
// occurrences of each element in the array.
void findFrequency(int arr[], int n)
{
    // HashMap to store frequencies
    unordered_map mp;
 
    // traverse the array
    for (int i = 0; i < n; i++) {
        // update the frequency
        mp[arr[i]]++;
    }
 
    // traverse the hashmap
    for (auto i : mp) {
        cout << "Element " << i.first << " occurs "
             << i.second << " times" << endl;
    }
}
 
// Driver function
int main()
{
    int arr[] = { 1, 1, 1, 2, 3, 3, 5, 5,
                  8, 8, 8, 9, 9, 10 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    findFrequency(arr, n);
 
    return 0;
}


Java
// Java program to count number
// of occurrences of each
// element in the array
import java.io.*;
import java.util.*;
class GFG
{
 
  // It prints number of
  // occurrences of each
  // element in the array.
  static void findFrequency(int [] arr,
                            int n)
  {
    Map mp
      = new HashMap();
 
    // traverse the array
    for (int i = 0; i < n; i++)
    {
 
      // update the frequency
      if (!mp.containsKey(arr[i]))
        mp.put(arr[i],0);
 
      mp.put(arr[i],mp.get(arr[i])+1);
    }
 
    // traverse the hashmap
    for (Map.Entry kvp : mp.entrySet())
    {
      System.out.println("Element " + kvp.getKey() +
                         " occurs " + kvp.getValue() +
                         " times");
    }
  }
 
  // Driver function
  public static void main (String[] args) {
 
 
    int [] arr = {1, 1, 1, 2,
                  3, 3, 5, 5,
                  8, 8, 8, 9,
                  9, 10};
    int n = arr.length;
    findFrequency(arr, n);
  }
}
 
// This code is contributed by avanitrachhadiya2155


Python3
# Python program to count number of occurrences of
# each element in the array #include 
 
# It prints number of
# occurrences of each element in the array.
def findFrequency(arr, n):
     
    # HashMap to store frequencies
    mp = {}
 
    # traverse the array
    for i in range(n):
 
        # update the frequency
        if arr[i] not in mp:
            mp[arr[i]] = 0
        mp[arr[i]] += 1
         
    # traverse the hashmap
    for i in mp:
        print("Element", i, "occurs", mp[i], "times")
     
# Driver function
arr = [1, 1, 1, 2, 3, 3, 5, 5,8, 8, 8, 9, 9, 10]
n = len(arr)
 
findFrequency(arr, n)
     
# This code is contributed by shubhamsingh10


C#
// C# program to count number
// of occurrences of each
// element in the array
using System;
using System.Collections.Generic;
class GFG{
 
// It prints number of
// occurrences of each
// element in the array.
static void findFrequency(int [] arr,
                          int n)
{
  // HashMap to store frequencies
  Dictionary  mp =
              new Dictionary();
 
  // traverse the array
  for (int i = 0; i < n; i++)
  {
    // update the frequency
    if (!mp.ContainsKey(arr[i]))
      mp[arr[i]] = 0;
 
    mp[arr[i]]++;
  }
 
  // traverse the hashmap
  foreach(KeyValuePair kvp in mp)
    Console.WriteLine("Element " + kvp.Key +
                      " occurs " + kvp.Value +
                      " times");
}
 
// Driver function
public static void Main()
{
  int [] arr = {1, 1, 1, 2,
                3, 3, 5, 5,
                8, 8, 8, 9,
                9, 10};
  int n = arr.Length;
  findFrequency(arr, n);
}
}
 
// This code is contributed by Chitranayal


C++
// C++ program to count number of occurrences of
// each element in the array in less than O(n) time
#include 
#include 
using namespace std;
 
// A recursive function to count number of occurrences
// for each element in the array without traversing
// the whole array
void findFrequencyUtil(int arr[], int low, int high,
                       vector& freq)
{
    // If element at index low is equal to element
    // at index high in the array
    if (arr[low] == arr[high]) {
        // increment the frequency of the element
        // by count of elements between high and low
        freq[arr[low]] += high - low + 1;
    }
    else {
        // Find mid and recurse for left and right
        // subarray
        int mid = (low + high) / 2;
        findFrequencyUtil(arr, low, mid, freq);
        findFrequencyUtil(arr, mid + 1, high, freq);
    }
}
 
// A wrapper over recursive function
// findFrequencyUtil(). It print number of
// occurrences of each element in the array.
void findFrequency(int arr[], int n)
{
    // create a empty vector to store frequencies
    // and initialize it by 0. Size of vector is
    // maximum value (which is last value in sorted
    // array) plus 1.
    vector freq(arr[n - 1] + 1, 0);
 
    // Fill the vector with frequency
    findFrequencyUtil(arr, 0, n - 1, freq);
 
    // Print the frequencies
    for (int i = 0; i <= arr[n - 1]; i++)
        if (freq[i] != 0)
            cout << "Element " << i << " occurs "
                 << freq[i] << " times" << endl;
}
 
// Driver function
int main()
{
    int arr[] = { 1, 1, 1, 2, 3, 3, 5, 5,
                  8, 8, 8, 9, 9, 10 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    findFrequency(arr, n);
 
    return 0;
}


Java
// Java program to count number of occurrences of
// each element in the array in less than O(n) time
import java.util.*;
 
class GFG {
 
    // A recursive function to count number of occurrences
    // for each element in the array without traversing
    // the whole array
    static void findFrequencyUtil(int arr[], int low,
                                  int high, int[] freq)
    {
        // If element at index low is equal to element
        // at index high in the array
        if (arr[low] == arr[high]) {
            // increment the frequency of the element
            // by count of elements between high and low
            freq[arr[low]] += high - low + 1;
        }
        else {
            // Find mid and recurse for left and right
            // subarray
            int mid = (low + high) / 2;
            findFrequencyUtil(arr, low, mid, freq);
            findFrequencyUtil(arr, mid + 1, high, freq);
        }
    }
 
    // A wrapper over recursive function
    // findFrequencyUtil(). It print number of
    // occurrences of each element in the array.
    static void findFrequency(int arr[], int n)
    {
        // create a empty vector to store frequencies
        // and initialize it by 0. Size of vector is
        // maximum value (which is last value in sorted
        // array) plus 1.
        int[] freq = new int[arr[n - 1] + 1];
 
        // Fill the vector with frequency
        findFrequencyUtil(arr, 0, n - 1, freq);
 
        // Print the frequencies
        for (int i = 0; i <= arr[n - 1]; i++)
            if (freq[i] != 0)
                System.out.println("Element " + i + " occurs " + freq[i] + " times");
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int arr[] = { 1, 1, 1, 2, 3, 3, 5,
                      5, 8, 8, 8, 9, 9, 10 };
        int n = arr.length;
 
        findFrequency(arr, n);
    }
}
 
// This code is contributed by 29AjayKumar


Python3
# Python 3 program to count number of occurrences of
# each element in the array in less than O(n) time
 
# A recursive function to count number of occurrences
# for each element in the array without traversing
# the whole array
def findFrequencyUtil(arr, low, high, freq):
     
    # If element at index low is equal to element
    # at index high in the array
    if (arr[low] == arr[high]):
         
        # increment the frequency of the element
        # by count of elements between high and low
        freq[arr[low]] += high - low + 1
     
    else:
         
        # Find mid and recurse for left 
        # and right subarray
        mid = int((low + high) / 2)
        findFrequencyUtil(arr, low, mid, freq)
        findFrequencyUtil(arr, mid + 1, high, freq)
     
# A wrapper over recursive function
# findFrequencyUtil(). It print number of
# occurrences of each element in the array.
def findFrequency(arr, n):
     
    # create a empty vector to store frequencies
    # and initialize it by 0. Size of vector is
    # maximum value (which is last value in sorted
    # array) plus 1.
    freq = [0 for i in range(n - 1 + 1)]
     
    # Fill the vector with frequency
    findFrequencyUtil(arr, 0, n - 1, freq)
 
    # Print the frequencies
    for i in range(0, arr[n - 1] + 1, 1):
        if (freq[i] != 0):
            print("Element", i, "occurs",
                        freq[i], "times")
 
# Driver Code
if __name__ == '__main__':
    arr = [1, 1, 1, 2, 3, 3, 5,
           5, 8, 8, 8, 9, 9, 10]
    n = len(arr)
    findFrequency(arr, n)
     
# This code is contributed by
# Surendra_Gangwar


C#
// C# program to count number of occurrences of
// each element in the array in less than O(n) time
using System;
 
class GFG {
 
    // A recursive function to count number of occurrences
    // for each element in the array without traversing
    // the whole array
    static void findFrequencyUtil(int[] arr, int low,
                                  int high, int[] freq)
    {
        // If element at index low is equal to element
        // at index high in the array
        if (arr[low] == arr[high]) {
            // increment the frequency of the element
            // by count of elements between high and low
            freq[arr[low]] += high - low + 1;
        }
        else {
            // Find mid and recurse for left and right
            // subarray
            int mid = (low + high) / 2;
            findFrequencyUtil(arr, low, mid, freq);
            findFrequencyUtil(arr, mid + 1, high, freq);
        }
    }
 
    // A wrapper over recursive function
    // findFrequencyUtil(). It print number of
    // occurrences of each element in the array.
    static void findFrequency(int[] arr, int n)
    {
        // create a empty vector to store frequencies
        // and initialize it by 0. Size of vector is
        // maximum value (which is last value in sorted
        // array) plus 1.
        int[] freq = new int[arr[n - 1] + 1];
 
        // Fill the vector with frequency
        findFrequencyUtil(arr, 0, n - 1, freq);
 
        // Print the frequencies
        for (int i = 0; i <= arr[n - 1]; i++)
            if (freq[i] != 0)
                Console.WriteLine("Element " + i + " occurs " + freq[i] + " times");
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        int[] arr = { 1, 1, 1, 2, 3, 3, 5,
                      5, 8, 8, 8, 9, 9, 10 };
        int n = arr.Length;
 
        findFrequency(arr, n);
    }
}
 
// This code is contributed by Princi Singh


Javascript


  • 输出:
Element 1 occurs 3 times
Element 2 occurs 1 times
Element 3 occurs 2 times
Element 5 occurs 2 times
Element 8 occurs 3 times
Element 9 occurs 2 times
Element 10 occurs 1 times
  • 复杂度分析:
    • 时间复杂度: O(n),只需要遍历数组一次。
    • 空间复杂度: O(n),用于将元素存储在HashMap中O(n)需要额外的空间。

方法2此方法使用二进制搜索技术来求解。

  • 方法:如果对所有元素进行排序,则可以在不到O(n)的时间内解决问题,即,如果数组中存在相似的元素,则这些元素位于连续的子数组中,或者可以说,如果子数组的末端为相同,则子数组中的所有元素都相等。因此,该元素的计数是子数组的大小,并且该子数组的所有元素都不需要计数。
  • 算法:
    1. 创建一个HashMap( hm )以存储元素的频率。
    2. 创建一个接受数组和大小的递归函数。
    3. 检查数组的第一个元素是否等于最后一个元素。如果相等,则所有元素都相同,并通过hm [array [0] + = size更新频率
    4. 否则,将数组分为两个相等的部分,并针对这两个部分递归调用函数。
    5. 遍历哈希图并打印元素频率对。
  • 执行:

C++

// C++ program to count number of occurrences of
// each element in the array in less than O(n) time
#include 
#include 
using namespace std;
 
// A recursive function to count number of occurrences
// for each element in the array without traversing
// the whole array
void findFrequencyUtil(int arr[], int low, int high,
                       vector& freq)
{
    // If element at index low is equal to element
    // at index high in the array
    if (arr[low] == arr[high]) {
        // increment the frequency of the element
        // by count of elements between high and low
        freq[arr[low]] += high - low + 1;
    }
    else {
        // Find mid and recurse for left and right
        // subarray
        int mid = (low + high) / 2;
        findFrequencyUtil(arr, low, mid, freq);
        findFrequencyUtil(arr, mid + 1, high, freq);
    }
}
 
// A wrapper over recursive function
// findFrequencyUtil(). It print number of
// occurrences of each element in the array.
void findFrequency(int arr[], int n)
{
    // create a empty vector to store frequencies
    // and initialize it by 0. Size of vector is
    // maximum value (which is last value in sorted
    // array) plus 1.
    vector freq(arr[n - 1] + 1, 0);
 
    // Fill the vector with frequency
    findFrequencyUtil(arr, 0, n - 1, freq);
 
    // Print the frequencies
    for (int i = 0; i <= arr[n - 1]; i++)
        if (freq[i] != 0)
            cout << "Element " << i << " occurs "
                 << freq[i] << " times" << endl;
}
 
// Driver function
int main()
{
    int arr[] = { 1, 1, 1, 2, 3, 3, 5, 5,
                  8, 8, 8, 9, 9, 10 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    findFrequency(arr, n);
 
    return 0;
}

Java

// Java program to count number of occurrences of
// each element in the array in less than O(n) time
import java.util.*;
 
class GFG {
 
    // A recursive function to count number of occurrences
    // for each element in the array without traversing
    // the whole array
    static void findFrequencyUtil(int arr[], int low,
                                  int high, int[] freq)
    {
        // If element at index low is equal to element
        // at index high in the array
        if (arr[low] == arr[high]) {
            // increment the frequency of the element
            // by count of elements between high and low
            freq[arr[low]] += high - low + 1;
        }
        else {
            // Find mid and recurse for left and right
            // subarray
            int mid = (low + high) / 2;
            findFrequencyUtil(arr, low, mid, freq);
            findFrequencyUtil(arr, mid + 1, high, freq);
        }
    }
 
    // A wrapper over recursive function
    // findFrequencyUtil(). It print number of
    // occurrences of each element in the array.
    static void findFrequency(int arr[], int n)
    {
        // create a empty vector to store frequencies
        // and initialize it by 0. Size of vector is
        // maximum value (which is last value in sorted
        // array) plus 1.
        int[] freq = new int[arr[n - 1] + 1];
 
        // Fill the vector with frequency
        findFrequencyUtil(arr, 0, n - 1, freq);
 
        // Print the frequencies
        for (int i = 0; i <= arr[n - 1]; i++)
            if (freq[i] != 0)
                System.out.println("Element " + i + " occurs " + freq[i] + " times");
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int arr[] = { 1, 1, 1, 2, 3, 3, 5,
                      5, 8, 8, 8, 9, 9, 10 };
        int n = arr.length;
 
        findFrequency(arr, n);
    }
}
 
// This code is contributed by 29AjayKumar

Python3

# Python 3 program to count number of occurrences of
# each element in the array in less than O(n) time
 
# A recursive function to count number of occurrences
# for each element in the array without traversing
# the whole array
def findFrequencyUtil(arr, low, high, freq):
     
    # If element at index low is equal to element
    # at index high in the array
    if (arr[low] == arr[high]):
         
        # increment the frequency of the element
        # by count of elements between high and low
        freq[arr[low]] += high - low + 1
     
    else:
         
        # Find mid and recurse for left 
        # and right subarray
        mid = int((low + high) / 2)
        findFrequencyUtil(arr, low, mid, freq)
        findFrequencyUtil(arr, mid + 1, high, freq)
     
# A wrapper over recursive function
# findFrequencyUtil(). It print number of
# occurrences of each element in the array.
def findFrequency(arr, n):
     
    # create a empty vector to store frequencies
    # and initialize it by 0. Size of vector is
    # maximum value (which is last value in sorted
    # array) plus 1.
    freq = [0 for i in range(n - 1 + 1)]
     
    # Fill the vector with frequency
    findFrequencyUtil(arr, 0, n - 1, freq)
 
    # Print the frequencies
    for i in range(0, arr[n - 1] + 1, 1):
        if (freq[i] != 0):
            print("Element", i, "occurs",
                        freq[i], "times")
 
# Driver Code
if __name__ == '__main__':
    arr = [1, 1, 1, 2, 3, 3, 5,
           5, 8, 8, 8, 9, 9, 10]
    n = len(arr)
    findFrequency(arr, n)
     
# This code is contributed by
# Surendra_Gangwar

C#

// C# program to count number of occurrences of
// each element in the array in less than O(n) time
using System;
 
class GFG {
 
    // A recursive function to count number of occurrences
    // for each element in the array without traversing
    // the whole array
    static void findFrequencyUtil(int[] arr, int low,
                                  int high, int[] freq)
    {
        // If element at index low is equal to element
        // at index high in the array
        if (arr[low] == arr[high]) {
            // increment the frequency of the element
            // by count of elements between high and low
            freq[arr[low]] += high - low + 1;
        }
        else {
            // Find mid and recurse for left and right
            // subarray
            int mid = (low + high) / 2;
            findFrequencyUtil(arr, low, mid, freq);
            findFrequencyUtil(arr, mid + 1, high, freq);
        }
    }
 
    // A wrapper over recursive function
    // findFrequencyUtil(). It print number of
    // occurrences of each element in the array.
    static void findFrequency(int[] arr, int n)
    {
        // create a empty vector to store frequencies
        // and initialize it by 0. Size of vector is
        // maximum value (which is last value in sorted
        // array) plus 1.
        int[] freq = new int[arr[n - 1] + 1];
 
        // Fill the vector with frequency
        findFrequencyUtil(arr, 0, n - 1, freq);
 
        // Print the frequencies
        for (int i = 0; i <= arr[n - 1]; i++)
            if (freq[i] != 0)
                Console.WriteLine("Element " + i + " occurs " + freq[i] + " times");
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        int[] arr = { 1, 1, 1, 2, 3, 3, 5,
                      5, 8, 8, 8, 9, 9, 10 };
        int n = arr.Length;
 
        findFrequency(arr, n);
    }
}
 
// This code is contributed by Princi Singh

Java脚本


  • 输出:
Element 1 occurs 3 times
Element 2 occurs 1 times
Element 3 occurs 2 times
Element 5 occurs 2 times
Element 8 occurs 3 times
Element 9 occurs 2 times
Element 10 occurs 1 times
  • 复杂度分析:
    • 时间复杂度: O(m log n)。
      其中m是大小为n的数组中不同元素的数量。由于m <= M(常数)(元素在有限范围内),因此此解决方案的时间复杂度为O(log n)。
    • 空间复杂度: O(n)。
      要将元素存储在HashMap O(n)中,需要额外的空间。