Hướng dẫn giải của Giá trị mang tần suất lẻ


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Lời giải này đang bị ẩn cho đến khi bạn chọn mở ra.

Chúng tôi khuyên bạn nên tự thử giải bài trước. Việc mở lời giải có thể làm lộ mất ý tưởng chính trước khi bạn có cơ hội tự giải.

Bạn phải đăng nhập để mở lời giải này.

Đăng nhập

Tác giả: Hiếu Nguyễn, nam7B2, DatBell, tonynguyen15hpvn

Hiểu bài toán

Bài toán yêu cầu tìm giá trị duy nhất trong một dãy số có độ dài lẻ n, trong đó mọi số khác đều xuất hiện đúng 2 lần (tần suất chẵn), chỉ có một số xuất hiện với tần suất lẻ (có thể là 1 lần, 3 lần...). Do độ dài dãy là số lẻ, số này chắc chắn tồn tại.

Các cách tiếp cận

Cách Hash Map (Sử dụng map)
#include <iostream>
#include <map>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    map<int, int> mp;

    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        mp[x]++;
    }

    for (auto p : mp) {
        if (p.second % 2 != 0) {
            cout << p.first << endl;
            break;
        }
    }

    return 0;
}
  • Time Complexity: O(n log n)
  • Space Complexity: O(n)

Sử dụng một map (hoặc hash map) để đếm tần suất xuất hiện của từng số. Sau khi nhập xong toàn bộ dãy, duyệt qua map và tìm số nào có tần suất lẻ. Do sử dụng map (cây đỏ-đen), thời gian chèn và tìm kiếm mỗi phần tử là O(log n), tổng thời gian là O(n log n).

Cách Bitwise XOR (Phép toán XOR)
#include <iostream>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    int result = 0;

    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        result ^= x;
    }

    cout << result << endl;

    return 0;
}
  • Time Complexity: O(n)
  • Space Complexity: O(1)

Tận dụng tính chất của phép toán XOR (khoảng loại): a ^ a = 0 và a ^ 0 = a. Vì mọi số xuất hiện chẵn lần sẽ triệt tiêu lẫn nhau (tổng XOR về 0), số còn lại sau khi XOR toàn bộ dãy chính là số xuất hiện lẻ lần. Ví dụ: 1 ^ 2 ^ 2 ^ 3 ^ 1 = (1^1) ^ (2^2) ^ 3 = 0 ^ 0 ^ 3 = 3.

Phân tích độ phức tạp

Cách tiếp cận Time Space Tên
1 O(n log n) O(n) Hash Map (Sử dụng map)
2 O(n) O(1) Bitwise XOR (Phép toán XOR)

Bài học kinh nghiệm

  • Phép toán XOR có tính chất 'khoảng loại' (a ^ a = 0), rất phù hợp để giải quyết bài toán tìm số xuất hiện lẻ lần khi các số khác xuất hiện chẵn lần.
  • Bài toán có thể được giải quyết trong thời gian tuyến tính O(n) và không gian hằng O(1) bằng cách sử dụng XOR thay vì dùng thêm bộ nhớ đếm tần suất.

Lỗi thường gặp

  • Nếu dùng map để đếm, cần lưu ý độ phức tạp thời gian O(n log n) có thể sát sao giới hạn nếu n rất lớn (10^6), mặc dù vẫn đủ thời gian chạy trong hầu hết trường hợp.
  • Cần đảm bảo biến lưu kết quả ban đầu được khởi tạo đúng (0 cho XOR) và kiểu dữ liệu đủ chứa giá trị đầu vào (dùng int hoặc long long tùy theo giới hạn a_i).

Bình luận

Please read the guidelines before commenting.


Không có bình luận tại thời điểm này.