📌  相关文章
📜  查找给定数组中出现次数最多的 k 个数字

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

给定一个由n 个数字和一个正整数k 组成的数组。问题是找到出现次数最多的k 个数字,即具有最大频率的前k 个数字。如果两个数字具有相同的频率,则应优先考虑较大的数字。数字应按其频率的降序显示。假设数组由k 个出现次数最多的数字组成。

例子:

在亚马逊面试中被问到

方法一:

  • 方法:思考过程应该从创建一个 HashMap 开始,将元素频率对存储在 HashMap 中。 HashMap 用于在恒定时间内执行插入和更新。然后按频率降序对元素-频率对进行排序。这给出了有关每个元素的信息以及它们在数组中出现的次数。要获取数组的 k 个元素,请打印已排序数组的前 k 个元素。
  • Hashmap: HashMap 从Java 1.2 开始就成为 Java 集合的一部分。它提供了Java Map 接口的基本实现。它将数据存储在(键,值)对中。要访问一个值,必须知道它的键。 HashMap 之所以称为 HashMap,是因为它使用了一种称为 Hashing 的技术。散列是一种将大字符串转换为表示相同字符串的小字符串的技术。较短的值有助于索引和更快的搜索。 HashSet 也在内部使用 HashMap。它在内部使用一个链接列表来存储键值对,这些键值对已经在 HashSet 和进一步的文章中详细解释过。
    更多关于 HashMap >>
  • 算法:
    1. 创建一个 Hashmap hm ,用于存储键值对,即元素频率对。
    2. 从头到尾遍历数组。
    3. 对于数组中的每个元素更新hm[array[i]]++
    4. 将元素频率对存储在向量中,并按频率降序对向量进行排序。
    5. 打印排序数组的前 k 个元素。

下面是上述算法的实现:

C++
// C++ implementation to find k numbers with most
// occurrences in the given array
#include 
 
using namespace std;
 
// comparison function to sort the 'freq_arr[]'
bool compare(pair p1, pair p2)
{
    // if frequencies of two elements are same
    // then the larger number should come first
    if (p1.second == p2.second)
        return p1.first > p2.first;
 
    // sort on the basis of decreasing order
    // of frequencies
    return p1.second > p2.second;
}
 
// funnction to print the k numbers with most occurrences
void print_N_mostFrequentNumber(int arr[], int n, int k)
{
    // unordered_map 'um' implemented as frequency hash table
    unordered_map um;
    for (int i = 0; i < n; i++)
        um[arr[i]]++;
 
    // store the elements of 'um' in the vector 'freq_arr'
    vector > freq_arr(um.begin(), um.end());
 
    // sort the vector 'freq_arr' on the basis of the
    // 'compare' function
    sort(freq_arr.begin(), freq_arr.end(), compare);
 
    // display the top k numbers
    cout << k << " numbers with most occurrences are:\n";
    for (int i = 0; i < k; i++)
        cout << freq_arr[i].first << " ";
}
 
// Driver program to test above
int main()
{
    int arr[] = { 3, 1, 4, 4, 5, 2, 6, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 2;
    print_N_mostFrequentNumber(arr, n, k);
    return 0;
}


Java
// Java implementation to find
// k elements with max occurrence.
import java.util.*;
public class KFrequentNumbers
{
    static void print_N_mostFrequentNumber(int[] arr,
                                           int n,
                                           int k)
    {
 
        Map mp
            = new HashMap();
 
        // Put count of all the
        // distinct elements in Map
        // with element as the key &
        // count as the value.
        for (int i = 0; i < n; i++) {
 
            // Get the count for the
            // element if already present in the
            // Map or get the default value which is 0.
            mp.put(arr[i],
                   mp.getOrDefault(arr[i], 0) + 1);
        }
 
        // Create a list from elements of HashMap
        List > list
            = new ArrayList >(
                mp.entrySet());
 
        // Sort the list
        Collections.sort(
            list,
            new Comparator >()
          {
                public int compare(
                    Map.Entry o1,
                    Map.Entry o2)
                {
                    if (o1.getValue() == o2.getValue())
                        return o2.getKey() - o1.getKey();
                    else
                        return o2.getValue()
                            - o1.getValue();
                }
            });
 
        for (int i = 0; i < k; i++)
            System.out.println(list.get(i).getKey());
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int arr[] = { 3, 1, 4, 4, 5, 2, 6, 1 };
        int n = arr.length;
        int k = 2;
         
        // Function call
        print_N_mostFrequentNumber(arr, n, k);
    }
}


Python3
# Python3 implementation to find k numbers
# with most occurrences in the given array
 
# funnction to print the k numbers with
# most occurrences
 
 
def pr_N_mostFrequentNumber(arr, n, k):
 
    um = {}
    for i in range(n):
        if arr[i] in um:
            um[arr[i]] += 1
        else:
            um[arr[i]] = 1
    a = [0] * (len(um))
    j = 0
    for i in um:
        a[j] = [i, um[i]]
        j += 1
    a = sorted(a, key=lambda x: x[0],
               reverse=True)
    a = sorted(a, key=lambda x: x[1],
               reverse=True)
 
    # display the top k numbers
    print(k, "numbers with most occurrences are:")
    for i in range(k):
        print(a[i][0], end=" ")
 
 
# Driver code
if __name__ == "__main__":
    arr = [3, 1, 4, 4, 5, 2, 6, 1]
    n = 8
    k = 2
    pr_N_mostFrequentNumber(arr, n, k)
 
# This code is contributed by
# Shubham Singh(SHUBHAMSINGH10)


Javascript


C++
// C++ implementation to find k numbers with most
// occurrences in the given array
#include 
 
using namespace std;
 
// comparison function defined for the priority queue
struct compare {
    bool operator()(pair p1, pair p2)
    {
        // if frequencies of two elements are same
        // then the larger number should come first
        if (p1.second == p2.second)
            return p1.first < p2.first;
 
        // insert elements in the priority queue on the basis of
        // decreasing order of frequencies
        return p1.second < p2.second;
    }
};
 
// funnction to print the k numbers with most occurrences
void print_N_mostFrequentNumber(int arr[], int n, int k)
{
    // unordered_map 'um' implemented as frequency hash table
    unordered_map um;
    for (int i = 0; i < n; i++)
        um[arr[i]]++;
 
     
 
    // priority queue 'pq' implemented as max heap on the basis
    // of the comparison operator 'compare'
    // element with the highest frequency is the root of 'pq'
    // in case of conflicts, larger element is the root
    priority_queue, vector >,
                compare>
        pq(um.begin(), um.end());
 
    // display the top k numbers
    cout << k << " numbers with most occurrences are:\n";
    for (int i = 1; i <= k; i++) {
        cout << pq.top().first << " ";
        pq.pop();
    }
}
 
// Driver program to test above
int main()
{
    int arr[] = { 3, 1, 4, 4, 5, 2, 6, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 2;
    print_N_mostFrequentNumber(arr, n, k);
    return 0;
}


Java
// Java implementation to find k
// elements with max occurrence.
import java.util.*;
public class KFrequentNumbers {
    static void print_N_mostFrequentNumber(int[] arr,
                                           int n,
                                           int k)
    {
        Map mp
            = new HashMap();
 
        // Put count of all the
        // distinct elements in Map
        // with element as the key &
        // count as the value.
        for (int i = 0; i < n; i++) {
 
            // Get the count for the
            // element if already
            // present in the Map or
            // get the default value
            // which is 0.
            mp.put(arr[i],
                   mp.getOrDefault(arr[i], 0) + 1);
        }
 
        // Create a Priority Queue
        // to sort based on the
        // count or on the key if the
        // count is same
        PriorityQueue> queue
            = new PriorityQueue<>(
                (a, b)
                -> a.getValue().equals(b.getValue())
                   ? Integer.compare(b.getKey(),
                                     a.getKey())
                   : Integer.compare(b.getValue(),
                                     a.getValue()));
 
        // Insert the data from the map
        // to the Priority Queue.
        for (Map.Entry entry :
             mp.entrySet())
            queue.offer(entry);
 
        // Print the top k elements
        for (int i = 0; i < k; i++)
        {
            System.out.println(queue.poll().getKey());
        }
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int arr[] = { 3, 1, 4, 4, 5, 2, 6, 1 };
        int n = arr.length;
        int k = 2;
       
        // Function call
        print_N_mostFrequentNumber(arr, n, k);
    }
}
 
// This code is contributed by Shubham Kumar Shah


Python3
# Python3 implementation to find k
# numbers with most occurrences in
# the given array
import heapq
 
# Function to print the k numbers with
# most occurrences
def print_N_mostFrequentNumber(arr, n, k):
     
    mp = dict()
     
    # Put count of all the distinct elements
    # in dictionary with element as the
    # key & count as the value.
    for i in range(0, n):
        if arr[i] not in mp:
            mp[arr[i]] = 0
        else:
            mp[arr[i]] += 1
             
    # Using heapq data structure
    heap = [(value, key) for key,
             value in mp.items()]
              
    # Get the top k elements
    largest = heapq.nlargest(k, heap)
 
    # Insert the data from the map to
    # the priority queue
    print(k, " numbers with most "
             "occurrences are:", sep = "")
              
    # Print the top k elements
    for i in range(k):
        print(largest[i][1], end =" ")
 
# Driver code
if __name__=="__main__":
     
    arr = [ 3, 1, 4, 4, 5, 2, 6, 1 ]
    n = len(arr)
    k = 2
     
    print_N_mostFrequentNumber(arr, n, k)
     
# This code is contributed by MuskanKalra1


Javascript


输出
2 numbers with most occurrences are:
4 1 

复杂度分析:

  • 时间复杂度: O(d log d),其中d是数组中不同元素的数量。对数组进行排序需要 O(d log d) 时间。
  • 辅助空间: O(d),其中d是数组中不同元素的数量。在 HashMap 中存储元素需要 O(d) 空间复杂度。

方法二:

  • 方法:创建一个HashMap,将元素频率对存储在HashMap中。 HashMap 用于在恒定时间内执行插入和更新。然后使用一个优先级队列来存储元素频率对(Max-Heap)。这给出了在优先队列根部具有最大频率的元素。删除优先队列 K 次的顶部或根并打印元素。插入和删除优先级队列的顶部需要O(log n)时间。
    优先队列:优先队列是一种容器适配器,专门设计成队列的第一个元素是队列中所有元素中最大的元素,并且元素不递增(因此我们可以看到队列的每个元素都有优先级{固定顺序})。
    关于优先队列的更多信息: C++ STL priority_queue
  • 算法 :
    1. 创建一个 Hashmap hm ,用于存储键值对,即元素频率对。
    2. 从头到尾遍历数组。
    3. 对于数组中的每个元素更新hm[array[i]]++
    4. 将元素频率对存储在优先队列中并创建优先队列,这需要 O(n) 时间。
    5. 运行循环 k 次,并在每次迭代中删除优先级队列的顶部并打印元素。

下面是上述算法的实现:

C++

// C++ implementation to find k numbers with most
// occurrences in the given array
#include 
 
using namespace std;
 
// comparison function defined for the priority queue
struct compare {
    bool operator()(pair p1, pair p2)
    {
        // if frequencies of two elements are same
        // then the larger number should come first
        if (p1.second == p2.second)
            return p1.first < p2.first;
 
        // insert elements in the priority queue on the basis of
        // decreasing order of frequencies
        return p1.second < p2.second;
    }
};
 
// funnction to print the k numbers with most occurrences
void print_N_mostFrequentNumber(int arr[], int n, int k)
{
    // unordered_map 'um' implemented as frequency hash table
    unordered_map um;
    for (int i = 0; i < n; i++)
        um[arr[i]]++;
 
     
 
    // priority queue 'pq' implemented as max heap on the basis
    // of the comparison operator 'compare'
    // element with the highest frequency is the root of 'pq'
    // in case of conflicts, larger element is the root
    priority_queue, vector >,
                compare>
        pq(um.begin(), um.end());
 
    // display the top k numbers
    cout << k << " numbers with most occurrences are:\n";
    for (int i = 1; i <= k; i++) {
        cout << pq.top().first << " ";
        pq.pop();
    }
}
 
// Driver program to test above
int main()
{
    int arr[] = { 3, 1, 4, 4, 5, 2, 6, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 2;
    print_N_mostFrequentNumber(arr, n, k);
    return 0;
}

Java

// Java implementation to find k
// elements with max occurrence.
import java.util.*;
public class KFrequentNumbers {
    static void print_N_mostFrequentNumber(int[] arr,
                                           int n,
                                           int k)
    {
        Map mp
            = new HashMap();
 
        // Put count of all the
        // distinct elements in Map
        // with element as the key &
        // count as the value.
        for (int i = 0; i < n; i++) {
 
            // Get the count for the
            // element if already
            // present in the Map or
            // get the default value
            // which is 0.
            mp.put(arr[i],
                   mp.getOrDefault(arr[i], 0) + 1);
        }
 
        // Create a Priority Queue
        // to sort based on the
        // count or on the key if the
        // count is same
        PriorityQueue> queue
            = new PriorityQueue<>(
                (a, b)
                -> a.getValue().equals(b.getValue())
                   ? Integer.compare(b.getKey(),
                                     a.getKey())
                   : Integer.compare(b.getValue(),
                                     a.getValue()));
 
        // Insert the data from the map
        // to the Priority Queue.
        for (Map.Entry entry :
             mp.entrySet())
            queue.offer(entry);
 
        // Print the top k elements
        for (int i = 0; i < k; i++)
        {
            System.out.println(queue.poll().getKey());
        }
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int arr[] = { 3, 1, 4, 4, 5, 2, 6, 1 };
        int n = arr.length;
        int k = 2;
       
        // Function call
        print_N_mostFrequentNumber(arr, n, k);
    }
}
 
// This code is contributed by Shubham Kumar Shah

蟒蛇3

# Python3 implementation to find k
# numbers with most occurrences in
# the given array
import heapq
 
# Function to print the k numbers with
# most occurrences
def print_N_mostFrequentNumber(arr, n, k):
     
    mp = dict()
     
    # Put count of all the distinct elements
    # in dictionary with element as the
    # key & count as the value.
    for i in range(0, n):
        if arr[i] not in mp:
            mp[arr[i]] = 0
        else:
            mp[arr[i]] += 1
             
    # Using heapq data structure
    heap = [(value, key) for key,
             value in mp.items()]
              
    # Get the top k elements
    largest = heapq.nlargest(k, heap)
 
    # Insert the data from the map to
    # the priority queue
    print(k, " numbers with most "
             "occurrences are:", sep = "")
              
    # Print the top k elements
    for i in range(k):
        print(largest[i][1], end =" ")
 
# Driver code
if __name__=="__main__":
     
    arr = [ 3, 1, 4, 4, 5, 2, 6, 1 ]
    n = len(arr)
    k = 2
     
    print_N_mostFrequentNumber(arr, n, k)
     
# This code is contributed by MuskanKalra1

Javascript


输出
2 numbers with most occurrences are:
4 1 

复杂度分析:

  • 时间复杂度: O(k log d + d),其中d是数组中不同元素的计数。
    移除优先级队列的顶部需要 O(log d) 时间,因此如果移除 k 个元素,则需要 O(k log d) 时间并且遍历不同元素需要 O(d) 时间。
  • 辅助空间: O(d),其中d是数组中不同元素的数量。
    在 HashMap 中存储元素需要 O(d) 空间复杂度。

找出线性时间内出现频率最高的 k
参考资料: https : //www.careercup.com/question?id=5082885552865280

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