Tôi tin rằng bạn có thể giải quyết vấn đề này bằng cách sử dụng biến thể trên tìm kiếm nhị phân. Trực giác đằng sau thuật toán này là như sau. Hãy để hai mảng là A và B và giả sử vì mục đích đơn giản là chúng có cùng kích thước (điều này là không cần thiết, như bạn sẽ thấy). Đối với mỗi mảng, chúng ta có thể xây dựng các mảng song song Ac và Bc sao cho cho mỗi chỉ số i, Ac [i] là số phần tử trong hai mảng không lớn hơn A [i] và Bc [i] là số các phần tử trong hai mảng không lớn hơn B [i]. Nếu chúng ta có thể xây dựng các mảng này một cách hiệu quả, thì chúng ta có thể tìm thấy phần tử nhỏ nhất thứ k một cách hiệu quả bằng cách thực hiện tìm kiếm nhị phân trên cả Ac và Bc để tìm giá trị k. Mục nhập tương ứng của A hoặc B cho mục nhập đó là phần tử lớn nhất thứ k. Tìm kiếm nhị phân là hợp lệ vì hai mảng Ac và Bc được sắp xếp, mà tôi nghĩ bạn có thể thuyết phục bản thân khá dễ dàng.
Tất nhiên, giải pháp này không hoạt động trong thời gian tuyến tính vì phải mất O (n) thời gian để xây dựng mảng Ac và Bc. Câu hỏi sau đó là - có cách nào để chúng tôi có thể ngầm định xây dựng các mảng này không? Đó là, chúng ta có thể xác định các giá trị trong các mảng này mà không nhất thiết phải xây dựng từng phần tử không? Tôi nghĩ rằng câu trả lời là có, sử dụng thuật toán này. Hãy bắt đầu bằng cách tìm kiếm mảng A để xem nó có giá trị nhỏ nhất kth hay không. Chúng ta biết rằng một giá trị nhỏ nhất thứ k không thể xuất hiện trong mảng trong mảng A sau vị trí k (giả sử tất cả các phần tử là khác nhau). Vì vậy, chúng ta hãy chỉ tập trung vào các phần tử k đầu tiên của mảng A. Chúng ta sẽ thực hiện tìm kiếm nhị phân trên các giá trị này như sau. Bắt đầu tại vị trí k/2; đây là phần tử nhỏ nhất k/2 trong mảng A. Bây giờ thực hiện tìm kiếm nhị phân trong mảng B để tìm giá trị lớn nhất trong B nhỏ hơn giá trị này và nhìn vào vị trí của nó trong mảng; đây là số phần tử trong B nhỏ hơn giá trị hiện tại. Nếu chúng ta thêm vị trí của các phần tử trong A và B, chúng ta có tổng số phần tử trong hai mảng nhỏ hơn phần tử hiện tại. Nếu đây chính xác là k, chúng ta đã xong. Nếu giá trị này nhỏ hơn k, thì chúng tôi sẽ chấp nhận nửa trên của các phần tử k đầu tiên của A và nếu điều này lớn hơn k, chúng tôi chấp nhận ở nửa dưới của các phần tử đầu tiên của k, v.v. Cuối cùng, chúng tôi sẽ thấy rằng phần tử lớn thứ k nằm trong mảng A, trong trường hợp này chúng ta đã hoàn thành. Nếu không, lặp lại quá trình này trên mảng B.
Thời gian chạy cho thuật toán này như sau. Việc tìm kiếm mảng A thực hiện tìm kiếm nhị phân trên các phần tử k, nó lấy các phép lặp O (lg k). Mỗi phép lặp giá thành O (lg n), vì chúng ta phải thực hiện tìm kiếm nhị phân trong B. Điều này có nghĩa là tổng thời gian cho tìm kiếm này là O (lg k lg n). Thời gian thực hiện điều này trong mảng B là như nhau, do đó thời gian chạy ròng cho thuật toán là O (lg k lg n) = O (lg n) = o (n), là tuyến dưới.
Tôi không nghĩ rằng điều này là có thể nhưng tôi sẽ được hạnh phúc để được chứng minh sai đó là lý do tại sao đây là một bình luận chứ không phải là một câu trả lời :-) Cách duy nhất để làm cho trích xuất chính nó O (1) là hợp nhất các danh sách là O (n).Bất kỳ giải pháp nào khác thiếu thông tin quan trọng về cách các số nguyên được phân bổ trong hai danh sách do đó bạn phải kiểm tra tất cả các giá trị trong chúng (phía trên cái bạn đang tìm) - điều này tự động làm cho nó O (n) tuyến tính. Nhưng tôi sẽ cung cấp cho bạn +1 cho một câu hỏi thú vị. – paxdiablo
@ paxdiablo- Bạn có thể kiểm tra câu trả lời của tôi và xem tôi có thiếu cái gì không? Tôi dường như đã nhận được điều này trong O (lg^2 n). – templatetypedef