Tìm phần tử nhỏ nhất thứ k từ một chuỗi đã cho chỉ với thời gian bộ nhớ O (k) O (n)


11

Giả sử rằng chúng ta đọc một chuỗi gồm n số, từng số một. Cách tìm phần tử nhỏ nhất thứ k chỉ bằng cách sử dụng bộ nhớ ô O(k) và trong thời gian tuyến tính ( O(n) ). Tôi nghĩ rằng chúng ta nên lưu các điều khoản đầu tiên kcủa chuỗi và khi nhận được thuật ngữ thứ k+1 , hãy xóa một thuật ngữ mà chúng tôi chắc chắn rằng nó không thể là phần tử nhỏ nhất của k và sau đó lưu thuật ngữ k+1 '. Vì vậy, chúng ta nên có một chỉ báo cho thấy thuật ngữ không thể sử dụng này trong mỗi bước và chỉ báo này sẽ được cập nhật nhanh chóng trong từng bước. Tôi bắt đầu với "max"; nhưng nó không thể cập nhật nhanh chóng; Có nghĩa là nếu chúng ta xem xét max thì trong lần xóa đầu tiên, chúng ta bỏ lỡ max và chúng ta nên tìm kiếm max trong O(k) và nguyên nhân của nó (nk)×O(k) mà nó không tuyến tính. Có lẽ chúng ta nên lưu k điều khoản đầu tiên của trình tự thông minh hơn.

Làm thế nào để tôi giải quyết vấn đề này?


1
Bạn có quan tâm đến một thuật toán trực tuyến, hoặc bất kỳ thuật toán sẽ làm gì?
Yuval Filmus

Nếu k=θ(n) sau đó bạn có thể làm điều đó bằng cách sử dụng thuật toán thống kê theo thứ tự. Nếu k=o(n) sau đó bạn có thể làm điều đó O(k) bộ nhớ và O(nlogk) thời gian sử dụng bất kỳ cây chiều cao cân bằng.
Shreesh

Nó được gọi là vấn đề lựa chọn en.wikipedia.org/wiki/Selection_alacticm
xavierm02

Có các thuật toán tại chỗ thời gian tuyến tính, mà bạn có thể google, nhưng chúng hơi phức tạp.
Yuval Filmus

@ xavierm02 không phải là vấn đề lựa chọn giống hệt nhau. Bởi vì có một hạn chế bộ nhớ.
Shahab_HK

Câu trả lời:


16

Tạo một bộ đệm có kích thước . Đọc trong 2 k phần tử từ mảng. Sử dụng thuật toán chọn thời gian tuyến tính để phân vùng bộ đệm sao cho k phần tử nhỏ nhất là đầu tiên; điều này mất thời gian O ( k ) . Bây giờ đọc trong k mục khác từ mảng của bạn vào bộ đệm, thay thế k mục lớn nhất trong bộ đệm, phân vùng bộ đệm như trước và lặp lại.2k2kkO(k)kk

Này có thời gian và O ( k ) không gian.O(kn/k)=O(n)O(k)


+1, điều này phù hợp với các tiệm cận được hỏi. Điều đó đang được nói, tôi không tin rằng điều này nhanh hơn so với thực hiện một thuật toán chọn thời gian tuyến tính duy nhất ... ngoại trừ khi là một hằng số nhỏ, thì nó cung cấp một viễn cảnh thú vị. Ví dụ với k = 1 thuật toán này tạo ra hàm. kk=1min
orlp

1
Đôi khi, thuật toán lựa chọn thời gian tuyến tính sử dụng quá nhiều không gian. Chẳng hạn, nó không phù hợp để sử dụng trong ngữ cảnh phát trực tuyến hoặc khi mảng đầu vào không thay đổi.
jbapple

Đó là những điểm hợp lệ.
orlp

3

Bạn có thể làm điều đó trong bộ nhớ và O ( n log k ) thời gian bằng cách hình thành một kích thước cố định max-đống từ đầu k yếu tố trong O ( k ) thời gian, sau đó lặp lại so với phần còn lại của mảng và đẩy một mới phần tử và sau đó bật cho O ( log k ) cho mọi phần tử cho tổng thời gian O ( k + n log k ) = O ( n log k ) .O(k)O(nlogk)kO(k)O(logk)O(k+nlogk)O(nlogk)

Bạn có thể thực hiện nó trong bộ nhớ phụ và thời gian O ( n ) bằng cách sử dụng thuật toán lựa chọn trung bình, chọn tại k và trả về các phần tử k đầu tiên . Không có thay đổi đối với tiệm cận, bạn có thể sử dụng introselect để tăng tốc độ trung bình. Đây là cách kinh điển để giải quyết vấn đề của bạn.O(logn)O(n)kk

Bây giờ về mặt kỹ thuật O ( k ) là không thể so sánh được. Tuy nhiên, tôi cho rằng O ( log n ) tốt hơn trong thực tế, vì nó thực sự không đổi khi xem xét không có hệ thống máy tính nào có nhiều hơn 2 64 byte bộ nhớ, log 2 64 = 64 . Trong khi đó k có thể phát triển lớn bằng n .O(logn)O(k)O(logn)264log264=64kn


O(n×logmin(k,nk))

@ xavierm02 = . Chứng minh: trường hợp xấu nhất cho là . Trường hợp xấu nhất cho là . Chúng giống nhau trong một yếu tố không đổi, do đó = . O ( k ) k n m i n ( k , n - k ) nO(min(k,nk))O(k)knmin(k,nk) O(min(k,n-k))O(k)n2O(min(k,nk))O(k)
orlp

@ xavierm02 Điều đó đang được nói, nó vẫn là một tốc độ tốt :)
orlp

un,k=kO(k)O(min(k,nk))CMMknkC(nk)n=k+).O(min(k,nk))O(k)

@ xavierm02 Tôi không quen thuộc với ký hiệu . Công bằng mà nói, tôi nói chung khá lạ lẫm với ký hiệu đa chiều , đặc biệt khi xem xét rằng kích thước không liên quan. O n , kun,kOn,k
orlp
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.