给定一个由n 个数字和一个正整数k 组成的数组。问题是找到出现次数最多的k 个数字,即具有最大频率的前k 个数字。如果两个数字具有相同的频率,则应优先考虑较大的数字。数字应按其频率的降序显示。假设数组由k 个出现次数最多的数字组成。
例子:
Input:
arr[] = {3, 1, 4, 4, 5, 2, 6, 1},
k = 2
Output: 4 1
Explanation:
Frequency of 4 = 2
Frequency of 1 = 2
These two have the maximum frequency and
4 is larger than 1.
Input :
arr[] = {7, 10, 11, 5, 2, 5, 5, 7, 11, 8, 9},
k = 4
Output: 5 11 7 10
Explanation:
Frequency of 5 = 3
Frequency of 11 = 2
Frequency of 7 = 2
Frequency of 10 = 1
These four have the maximum frequency and
5 is largest among rest.
在亚马逊面试中被问到
方法一:
- 方法:思考过程应该从创建一个 HashMap 开始,将元素频率对存储在 HashMap 中。 HashMap 用于在恒定时间内执行插入和更新。然后按频率降序对元素-频率对进行排序。这给出了有关每个元素的信息以及它们在数组中出现的次数。要获取数组的 k 个元素,请打印已排序数组的前 k 个元素。
- Hashmap: HashMap 从Java 1.2 开始就成为 Java 集合的一部分。它提供了Java Map 接口的基本实现。它将数据存储在(键,值)对中。要访问一个值,必须知道它的键。 HashMap 之所以称为 HashMap,是因为它使用了一种称为 Hashing 的技术。散列是一种将大字符串转换为表示相同字符串的小字符串的技术。较短的值有助于索引和更快的搜索。 HashSet 也在内部使用 HashMap。它在内部使用一个链接列表来存储键值对,这些键值对已经在 HashSet 和进一步的文章中详细解释过。
更多关于 HashMap >> - 算法:
- 创建一个 Hashmap hm ,用于存储键值对,即元素频率对。
- 从头到尾遍历数组。
- 对于数组中的每个元素更新hm[array[i]]++
- 将元素频率对存储在向量中,并按频率降序对向量进行排序。
- 打印排序数组的前 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 - 算法 :
- 创建一个 Hashmap hm ,用于存储键值对,即元素频率对。
- 从头到尾遍历数组。
- 对于数组中的每个元素更新hm[array[i]]++
- 将元素频率对存储在优先队列中并创建优先队列,这需要 O(n) 时间。
- 运行循环 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 现场工作专业课程和学生竞争性编程现场课程。