Cách nhanh nhất để tìm giá trị nhỏ nhất thứ K trong danh sách chưa sắp xếp mà không cần sắp xếp là gì?


8

Thuật toán ban đầu của tôi:

  1. So sánh phần tử 0 với mọi phần tử khác, theo dõi xem có bao nhiêu phần tử nhỏ hơn nó.
  2. Lặp lại cho mỗi phần tử cho đến khi một phần tử lớn hơn các phần tử chính xác (k-1) được tìm thấy.

Tôi cho rằng điều này sẽ mất trong trường hợp xấu nhất. Một thời gian chạy nhanh hơn có thể đạt được mà không cần sắp xếp danh sách?O(n2)



Bạn có thể tạo một danh sách thứ hai, và sắp xếp nó? Tức là bạn có thể tạo một danh sách các giá trị k nhỏ nhất không?
jmoreno

Câu trả lời:


10

Sử dụng thuật toán lựa chọn cho thời gian tuyến tính https://en.m.wikipedia.org/wiki/Selection_alacticm


2
Cụ thể là Median of Median của Blum et al., 1973, giải quyết vấn đề lựa chọn trong thời gian tuyến tính trong trường hợp xấu nhất. Có lẽ là thuật toán thanh lịch nhất mà tôi từng thấy.
quicksort

6
Mặc dù điều này trả lời câu hỏi, nó được khuyến khích để mô tả riêng, không chỉ là một liên kết.
Ác

4

Thật không may, tôi không thể bình luận nhưng tôi phải đăng nó như một câu trả lời.

Dù sao, bạn có thể thử sử dụng một heap nhỏ trên mảng chưa được sắp xếp của mình, bạn sẽ có thể có được độ phức tạp thời gian của O (n + k * logn).


3
Thật không may, tôi không thể bình luận nhưng tôi phải đăng nó như một câu trả lời. - đó là một điều tốt, vì câu trả lời như bài đăng của bạn không thuộc về các bình luận. Nhận xét là để cải thiện các câu hỏi, không phải cho câu trả lời ngắn hoặc tương tự.
Wrzlprmft

1
Mh, tôi cảm thấy như của tôi không phải là một câu trả lời đầy đủ để thành thật, tôi đã không đưa ra bất kỳ chi tiết cụ thể nào về việc tại sao hoặc việc sử dụng một đống nhỏ có thể làm giảm sự phức tạp thời gian, đó là lý do tại sao tôi cảm thấy như nó thuộc về nhiều hơn trong một bình luận hơn là trong một câu trả lời
Luca Giorgi

Nó phụ thuộc vào nên sử dụng min-heap hay max-heap. k
Ác

3

Thuật toán Quickselect có thể làm điều đó với độ phức tạp trung bình O (n), nó là một trong những thuật toán lựa chọn được sử dụng thường xuyên nhất theo Wikipedia .

Nó có nguồn gốc từ QuickSort và do đó có độ phức tạp trong trường hợp xấu nhất O (n²) nếu bạn sử dụng trục xoay xấu (một vấn đề có thể tránh được trong thực tế).

Thuật toán tóm tắt: Sau khi xoay vòng như trong QuickSort, chỉ đi xuống phía dưới hoặc phía cao hơn của mảng - tùy thuộc vào yếu tố nào trong số chúng có phần tử mà bạn theo sau.


2

kk

  1. k
  2. i
    • M
    • i<MMi

k

O(k)O(n.logk)


1
Max-heap hoặc Min-heap, nó phụ thuộc vào k> n / 2.
Ác

@Evil Bạn muốn kiểm tra xem tôi có nhỏ hơn bất kỳ phần tử nào trong heap không. Vì vậy, bạn muốn biết liệu nó nhỏ hơn lớn nhất trong số họ. Tra cứu phần tử tối đa là O (1) trong heap tối đa, nhưng không phải trong heap tối thiểu.
Behrouz Babaki

1
Thật. Hãy tưởng tượng rằng k = 1 hoặc k = n, bạn sẽ sử dụng cùng một đống trong cả hai trường hợp? Có lẽ có thể sử dụng min-heap bằng cách nào đó khi nó nhanh hơn? (Tôi biết đó là, bạn có +1 từ tôi, chỉ là một kẻ lừa đảo, đừng lo lắng).
Ác

1
@Evil Bạn nói đúng. Tôi vội vứt bình luận của bạn. Khi k> n / 2, người ta có thể sử dụng một phương thức tương tự để lưu trữ các phần tử lớn nhất (nk) trong một heap. Các yếu tố loại bỏ khỏi đống là những gì chúng ta muốn.
Behrouz Babaki
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.