Hướng dẫn giải của Gộp mảng


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, duykhanh100106, Namdo, LamThanhVu

Editorial for ptit064: Gộp mảng

Hiểu bài toán

Cho hai mảng A và B, mỗi mảng có n phần tử, đã được sắp xếp không giảm. Nhiệm vụ là tạo ra mảng C chứa tất cả các phần tử của A và B (tổng cộng 2n phần tử) và sắp xếp chúng theo thứ tự không giảm. Vấn đề này về cơ bản là gộp (merge) hai mảng đã được sắp xếp.

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

Cách Sử dụng hàm qsort (Concatenate then Sort)
#include<stdio.h>
#include<stdlib.h>

int cmp(const void *a, const void *b) {
    return (*(int*)a - *(int*)b);
}

int main() {
    int n;
    scanf("%d", &n);
    int c[2 * n], k = 0;
    for(int i = 0; i < n; i++) scanf("%d", &c[k++]);
    for(int j = 0; j < n; j++) scanf("%d", &c[k++]);
    qsort(c, 2 * n, sizeof(int), cmp);
    for(int l = 0; l < 2 * n; l++) printf("%d ", c[l]);
    return 0;
}
  • Time Complexity: O(n log n)
  • Space Complexity: O(n)

Cách tiếp cận này đọc tất cả các phần tử của hai mảng vào một mảng lớn hơn (C), sau đó sử dụng hàm qsort để sắp xếp lại mảng C. Đây là cách đơn giản nhất để giải quyết bài toán, nhưng không tận dụng được việc hai mảng ban đầu đã được sắp xếp sẵn.

Cách Thuật toán Trộn hai mảng (Merge Two Sorted Arrays)
#include <stdio.h>

int main() {
    int n;
    scanf("%d", &n);
    int a[100000], b[100000];
    int ans[200000];
    for(int i = 0; i < n; i++) scanf("%d", &a[i]);
    for(int i = 0; i < n; i++) scanf("%d", &b[i]);

    int i = 0, j = 0, cnt = 0;
    while (i < n && j < n) {
        if (a[i] <= b[j]) {
            ans[cnt++] = a[i++];
        } else {
            ans[cnt++] = b[j++];
        }
    }
    while (i < n) ans[cnt++] = a[i++];
    while (j < n) ans[cnt++] = b[j++];

    for (int k = 0; k < cnt; k++) {
        printf("%d ", ans[k]);
    }
    return 0;
}
  • Time Complexity: O(n)
  • Space Complexity: O(n)

Đây là thuật toán chuẩn để trộn hai mảng đã được sắp xếp. Sử dụng hai biến chỉ thị (pointer) cho từng mảng, ta duyệt qua cả hai mảng và so sánh các phần tử hiện tại. Phần tử nhỏ hơn được thêm vào mảng kết quả và chỉ số của mảng đó được tăng lên. Cách này hiệu quả hơn nhiều so với việc sắp xếp lại toàn bộ mảng.

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) Sử dụng hàm qsort (Concatenate then Sort)
2 O(n) O(n) Thuật toán Trộn hai mảng (Merge Two Sorted Arrays)

Bài học kinh nghiệm

  • Việc hai mảng đầu vào đã được sắp xếp là manh mối quan trọng để tối ưu hóa bài toán.
  • Thuật toán trộn mảng (Merge Algorithm) là nền tảng cơ bản trong nhiều thuật toán sắp xếp hiệu quả như Merge Sort.

Lỗi thường gặp

  • Cần phân bổ đủ bộ nhớ cho mảng kết quả (2*n phần tử).
  • Sai sót trong việc xử lý các phần tử còn sót lại sau khi một trong hai mảng đã duyệt hết (hai vòng lặp while cuối cùng).

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.