Tìm trung vị của mảng chưa sắp xếp trong thời gian


45

Để tìm trung bình của một mảng không được phân loại, chúng ta có thể làm cho một min-heap trong thời gian cho n yếu tố, và sau đó chúng ta có thể trích xuất từng người một n / 2 yếu tố để có được trung bình. Nhưng phương pháp này sẽ mất thời gian O ( n log n ) .O(nlogn)nn/2O(nlogn)

Chúng ta có thể làm tương tự bằng một số phương pháp trong thời gian không? Nếu chúng ta có thể, thì làm thế nào?O(n)



1
@JukkaSuomela Tại sao không làm cho câu trả lời nhanh chóng và đơn giản này (với một lời giải thích ngắn về một thuật toán như vậy, lý tưởng)?
Raphael

2
Lưu ý các cuộc thảo luận meta liên quan ; Hóa ra, các tìm kiếm trên web đơn giản dẫn đến câu trả lời cho câu hỏi này.
Raphael

Câu trả lời:


45

Đây là trường hợp đặc biệt của thuật toán lựa chọn có thể tìm phần tử nhỏ thứ của một mảng với k là một nửa kích thước của mảng. Có một thực hiện là tuyến tính trong trường hợp xấu nhất.kk

Thuật toán lựa chọn chung

Trước tiên, hãy xem một thuật toán find-kthtìm phần tử nhỏ thứ của một mảng:k

find-kth(A, k)
  pivot = random element of A
  (L, R) = split(A, pivot)
  if k = |L|+1, return pivot
  if k ≤ |L|  , return find-kth(L, k)
  if k > |L|+1, return find-kth(R, k-(|L|+1))

Hàm split(A, pivot)trả về L,Rsao cho tất cả các phần tử trong Rlớn hơn pivotLtất cả các phần tử khác (trừ một lần xuất hiện pivot). Sau đó tất cả được thực hiện đệ quy.

O(n)O(n2)

Trường hợp xấu nhất tuyến tính: thuật toán trung bình trung bình

Một trục tốt hơn là trung vị của tất cả các trung vị của các mảng con Acó kích thước 5, bằng cách sử dụng thủ tục trên mảng của các trung vị này.

find-kth(A, k)
  B = [median(A[1], .., A[5]), median(A[6], .., A[10]), ..]
  pivot = find-kth(B, |B|/2)
  ...

O(n)

Lưu ý rằng hầu hết thời gian sử dụng trục ngẫu nhiên là nhanh hơn.


Là kích thước 5tiêu chuẩn? Nếu kích thước của A nhỏ hơn 5 thì sao?
Jayesh

Đối với bất kỳ n cố định, độ phức tạp là không đổi, trừ khi nó là vô hạn. Vì vậy, bạn có thể sử dụng bất kỳ thuật toán hợp lệ nào với độ phức tạp hữu hạn cho trường hợp đặc biệt như vậy, ngay cả khi đó là O (2 ^ n). Đối với một n cố định (nghĩa là nhiều nhất là 4 trong trường hợp ngoài), độ phức tạp nhiều nhất là O (2 ^ 4) = O (1).
v6ak

3
Trên thuật toán đầu tiên: return A[k]không chính xác (trừ khi Ađược sắp xếp sẽ làm cho thuật toán di chuyển). Nếu splittình cờ chia Anhư vậy mà k = |L| + 1bạn vẫn không biết kphần tử thứ đó ở đâu . Trường hợp cơ sở của bạn là khi |A| = 1khác bạn vẫn cần thực hiện một trong hai cuộc gọi đệ quy.
wcochran

2
@NickCaplinger đã sửa lỗi bằng
web.archive.org

1
Không phải là trường hợp xấu nhất cho thuật toán lựa chọn chung O (NlogN)? Ngay cả khi cuộc gọi đệ quy chỉ để lại 10% mảng sau mỗi cuộc gọi, thì đó vẫn là logarit trong cơ sở 10.
octavian

6

n1/4O(n)

Ý tưởng chính của thuật toán là sử dụng lấy mẫu. Chúng ta phải tìm hai phần tử gần nhau theo thứ tự sắp xếp của mảng và có trung tuyến nằm giữa chúng. Xem tài liệu tham khảo [MU2017] để thảo luận đầy đủ.


[MU2017] Michael Mitzenmacher và Eli Upfal. "Xác suất và tính toán: Kỹ thuật ngẫu nhiên và xác suất trong thuật toán và phân tích dữ liệu", chương 3, trang 57-62. Nhà xuất bản Đại học Cambridge, tái bản lần thứ hai, 2017.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.