Các phần tử xuất hiện nhiều nhất

Đề bài

Cho một mảng số nguyên nums và một số nguyên k, trả về k phần tử xuất hiện nhiều nhất trong mảng. Bạn có thể trả về các phần tử này theo bất kỳ thứ tự nào.

Ví dụ 1:
Đầu vào: nums = [1,1,1,2,2,3], k = 2

Đầu ra: [1,2]

Ví dụ 2:
Đầu vào: nums = [1], k = 1

Đầu ra: [1]

Ràng buộc:
1 <= nums.length <= 100,000
-10,000 <= nums[i] <= 10,000
k nằm trong khoảng [1, số lượng phần tử duy nhất trong mảng].
Đáp án chắc chắn là duy nhất.
Yêu cầu bổ sung: Độ phức tạp của thuật toán phải tốt hơn O(n log n), trong đó n là kích thước của mảng.
Giải pháp:
Một cách tiếp cận hiệu quả là sử dụng unordered_map để đếm tần số xuất hiện của các phần tử và sử dụng cấu trúc heap để tìm k phần tử xuất hiện nhiều nhất.

Cách làm

#include <iostream>
#include <unordered_map>
#include <queue>
using namespace std;

void topKFrequent(int nums[], int n, int k, int ketqua[]) {
    unordered_map<int, int> tanSo;
    
    // Đếm tần số xuất hiện của từng phần tử
    for (int i = 0; i < n; i++) {
        tanSo[nums[i]]++;
    }

    // Sử dụng heap (priority queue) để giữ k phần tử có tần số lớn nhất
    priority_queue<pair<int, int>> pq;

    for (auto &it : tanSo) {
        pq.push({it.second, it.first});
    }

    // Lấy k phần tử có tần số lớn nhất
    for (int i = 0; i < k; i++) {
        ketqua[i] = pq.top().second;
        pq.pop();
    }
}

int main() {
    int nums[] = {1, 1, 1, 2, 2, 3};
    int n = sizeof(nums) / sizeof(nums[0]);
    int k = 2;
    int ketqua[k];
    
    topKFrequent(nums, n, k, ketqua);
    
    cout << "Cac phan tu xuat hien nhieu nhat la: ";
    for (int i = 0; i < k; i++) {
        cout << ketqua[i] << " ";
    }
    cout << endl;

    return 0;
}

Bình luận