Tìm trung vị của một danh sách các mảng được sắp xếp


8

Input: Một tập hợp các mảng A i (các số). Các phần tử trong mỗi mảng được sắp xếp theo thứ tự, nhưng tập hợp các mảng không nhất thiết phải được sắp xếp. Các mảng không nhất thiết phải có cùng kích thước. Tổng số phần tử là n .Ai
n

Đầu ra: Phần tử nhỏ thứ trong số tất cả các phần tử trong đầu vào.k

Thuật toán hiệu quả nhất cho vấn đề này là gì?

Là nó có thể, ví dụ để đạt được một thời gian chạy của ?O(+logn)


Có một câu hỏi liên quan rất chặt chẽ về SO , với câu trả lời không thỏa đáng.
Joe

Có phải tất cả các mảng có cùng độ dài?
vonbrand

Các mảng không nhất thiết phải có cùng kích thước. Tuy nhiên, tôi cũng quan tâm đến một trường hợp đặc biệt trong đó các kích thước là hình học, đó là mảng có kích thước n / 2 i , nhưng tôi nghi ngờ nó sẽ giúp ích trong thời gian chạy. Ain/2i
Joe

4
Làm thế nào để bạn có được ? Bạn có thể lấy O ( ( log n ) 2 ) bằng cách bắt chước các "quickselect" thuật toán. Trong mỗi giai đoạn, bạn chọn một trục và tính toán có bao nhiêu phần tử bên dưới nó, trong O ( log n ) . Sau đó, bạn loại bỏ các yếu tố ở phía sai, và lặp lại. Quá trình kết thúc sau các lần lặp log n (trong kỳ vọng hoặc trong trường hợp xấu nhất nếu bạn chọn trục xoay một cách thông minh). O(logn)O((logn)2)O(logn)logn
Yuval Filmus

2
@Joe Tôi nghĩ bạn cũng nên mô tả thuật toán của mình. Nó sẽ rất thú vị, và có thể cung cấp một điểm khởi đầu cho các thuật toán tốt hơn nếu đúng. Nếu không chính xác, mọi người có thể tìm thấy bất kỳ lỗi nào.
Paresh

Câu trả lời:


5

Bạn có thể làm điều đó trong thời gian và không gian thêm O ( l ) như sau:O(l+k log l)O(l)

  1. Xây dựng một đống nhị phân với một mục nhập cho mỗi mảng. Khóa cho mục là phần tử nhỏ nhất trong mảng A i . Cái này mấtiAithời gian O ( l ) .O(l)
  2. Chọn mục nhập nhỏ nhất từ ​​heap và loại bỏ nó (mất thời gian )). Thêm mục nhập đó trở lại heap bằng cách sử dụng mục nhập nhỏ nhất tiếp theo trong mảng có liên quan làm khóa của nó (lại là thời gian O ( log  l ) ).O(log lO(log l)
  3. Làm bước trước lần. Yếu tố cuối cùng bạn loại bỏ khỏi heap là câu trả lời của bạn.k

Nếu bạn thay thế heap nhị phân bằng heap Fibonacci, tôi nghĩ rằng điều này sẽ khiến bạn giảm thời gian khấu hao , nhưng trên thực tế, nó sẽ chậm hơn heap nhị phân trừ khi l là LỚN.O(l+k)l

Tôi nghi ngờ rằng giới hạn heap Fibonacci là tối ưu, bởi vì theo trực giác, bạn sẽ phải kiểm tra ít nhất phần tử để tìm phần tử nhỏ thứ k và bạn sẽ phải kiểm tra ít nhất một phần tử từ mỗi phần tử l mảng vì bạn không biết làm thế nào họ đang sắp xếp, mà ngay lập tức đưa ra một giới hạn thấp hơn của Ω ( max ( k , l ) ) = Ω ( k + l ) .kklΩ(max(k,l))=Ω(k+l)


3
Bạn không phải kiểm tra ít nhất phần tử vì các mảng được sắp xếp. Xem các giải pháp trong nhận xét của tôi, mang đến cho O ( ( log n ) 2 ) . kO((logn)2)
Yuval Filmus

1
Bạn có thể cải thiện thời gian chạy trường hợp xấu nhất trong mô hình RAM, vì bạn có thể triển khai hàng đợi ưu tiên của mình cho phần tử trong o ( log n ) . Trong mô hình này, bạn có thể đạt được cho cả chèn và các hoạt động xóa O ( no(logn)O(1)thời gian cho hoạt động findMin. O(loglogn)O(1)
Massimo Cafaro

1
Bạn có chắc chắn heap Fibonnaci hỗ trợ hoạt động đúng không? Tôi nghĩ rằng bạn đang nghĩ về việc giảm -key trong một đống.
Joe

Điều này về cơ bản giống như câu trả lời của vonbrand, với quan sát thêm rằng bạn không phải hợp nhất bất kỳ yếu tố nào sau câu thứ k.
Joe

O(1)k

5

O(log2n) algorithm. It can probably be derandomized using the same trick used to derandomize the usual quickselect.

We emulate the classical quickselect algorithm. In each phase, you pick a pivot and calculate how many elements are below it, in O(logn), using binary search in each list. Then you remove elements on the wrong side, and repeat. The process ends after logn iterations in expectation.


1

This seems to be resolved by the paper Generalized selection and ranking (Preliminary Version) by Frederickson and Johnson in STOC '80.

They give upper and lower bounds of: Θ(+i=1log|Ai|) which turns out to be logn for most array size distributions.

The actual algorithm to achieve the upper bound is apparently given in a previous paper: Optimal algorithms for generating quantile information in X+Y and matrices with sorted columns, Proc. 13th Annual Conference on Information Science and Systems, The Johns Hopkins University (1979) 47-52.


0

An -way merge takes time Θ(nlog) (use an efficient way to represent a priority queue of the head elements in each list), then you pick the k-th element in constant time. I think this is discussed in Knuth's "Sorting and searching" for sorting. Getting the smallest (or largest) clearly takes Θ(), for an unsorted array it is O(n) IIRC.

Please describe your algorithm.


1
This is way slower than I'm interested in. You can find the median in O(n) time just concatenating the lists and using the linear time selection algorithm.
Joe
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.