2010-12-30 40 views
17

Có ai biết cấu trúc dữ liệu hỗ trợ hai thao tác một cách hiệu quả không?Cấu trúc dữ liệu để chọn các phần tử ngẫu nhiên?

  1. Chèn giá trị vào cấu trúc dữ liệu.
  2. Hủy bỏ và trả lại mục nhập từ cấu trúc dữ liệu với xác suất ngẫu nhiên thống nhất.

Đây giống như "túi bi" kinh điển luôn xuất hiện trong các lớp xác suất giới thiệu. Bạn có thể đặt các viên bi tùy ý vào trong túi, và sau đó có thể loại bỏ các viên bi một cách hiệu quả một cách ngẫu nhiên.

Giải pháp tốt nhất tôi có được như sau - sử dụng cây tìm kiếm nhị phân tự cân bằng (AVL, AA, đỏ/đen, v.v.) để lưu trữ các phần tử. Điều này cho thời gian chèn O (lg n). Để loại bỏ một phần tử ngẫu nhiên, chọn một chỉ số ngẫu nhiên i, sau đó tìm và loại bỏ phần tử thứ i từ cây. Nếu bạn đã tăng cường cấu trúc một cách thích hợp, điều này có thể được thực hiện để chạy trong thời gian O (lg n).

Thời gian chạy này chắc chắn không phải là xấu, nhưng tôi tò mò nếu nó có thể làm tốt hơn - có lẽ O (1) để chèn và O (lg n) cho dequeues? Hoặc có lẽ một cái gì đó chạy trong mong đợi O (1) chèn và xóa bằng cách sử dụng hàm băm? Hoặc có lẽ một ràng buộc amortized mạnh hơn?

Có ai có ý tưởng nào về cách thực hiện điều này nhanh hơn không?

+0

Chỉ vì tò mò: có ai biết liệu cấu trúc dữ liệu này có tên không? Đó rõ ràng là một loại 'Bag' và/hoặc' MultiSet'. 'RandomBag', có thể? Trong thực tế, cấu trúc dữ liệu như thế nào (tức là cấu trúc dữ liệu trong đó 'pop' trả về và loại bỏ một phần tử ngẫu nhiên) được gọi là * nói chung *? –

+0

Tôi đã nghe các điều khoản Bag và RandomBag được sử dụng ở đây, nhưng tôi nghĩ RandomBag có lẽ là thuật ngữ thích hợp; Túi thường là một từ đồng nghĩa với multiset. – templatetypedef

Trả lời

35

Có. Sử dụng một vector.

Để chèn, chỉ cần đặt ở cuối và tăng kích thước. Để loại bỏ, chọn một phần tử một cách ngẫu nhiên, hoán đổi nội dung của nó với giá trị kết thúc, sau đó bật giá trị kết thúc (tức là trả về giá trị cuối và giảm kích thước của vectơ).

Cả hai hoạt động được khấu hao O (1).

+5

Khi bạn không cần phải giữ trật tự, cấu trúc dữ liệu rất đơn giản :) –

+1

Đẹp! Đó là một giải pháp tuyệt vời. Cám ơn rất nhiều! – templatetypedef

+3

@templatetypedef: Niềm vui của tôi. :-) BTW, nếu bạn đang áp dụng cho Google, bạn dự kiến ​​sẽ biết rằng phương pháp này về cơ bản là một biến thể của Fisher-Yates shuffle. Ngoại trừ điều đó thay vì để các giá trị xáo trộn trong mảng, bạn sẽ giải nén chúng ra. :-P –

Các vấn đề liên quan