2017-11-27 34 views
6

Tôi có một số List<Long> (A) cho biết kích thước miễn phí có sẵn cho các phân vùng khác nhau. Người dùng đến hỏi với List<Long> (B) cho biết kích thước tệp mà họ muốn lưu trữ.Tìm nếu Long (trong danh sách) có thể vừa với Danh sách các giá trị Dài

Bây giờ nếu bất kỳ Long (từ B) có thể phù hợp với bất kỳ kích thước miễn phí trong A, chúng tôi muốn tái sử dụng phân vùng, nếu không tạo phân vùng mới cho chúng.

Làm thế nào tôi có thể biết nếu có giá trị Long từ B có giá trị nhỏ hơn bất kỳ Long trong A.

Nếu tôi sử dụng phương pháp lặp đi lặp lại để quét qua A và tìm hiểu nếu có của B sẽ phù hợp, nó sẽ gây ra thời gian chạy O (n^2), nhưng chúng ta có thể làm tốt hơn không?

Mọi cấu trúc dữ liệu tồn tại cho loại sự cố này?

+2

Nếu bạn giữ A sắp xếp, bạn có thể kiểm tra hàng đầu theo thời gian cố định hoặc tìm phân vùng nhỏ nhất có sẵn với tìm kiếm nhị phân. – shmosel

+0

Giữ nó được sắp xếp nếu thêm nhiều gánh nặng tại thời điểm lưu trữ. Và ngay cả khi chúng tôi sử dụng tìm kiếm nhị phân, nó có thể không hiệu quả. Ví dụ: các kích thước miễn phí có thể là 1G, 2G, 3GB và người dùng sẽ yêu cầu tệp 100 MB. Sau đó, chúng tôi sẽ muốn sử dụng các khe miễn phí của 1G thay vì 2G. –

+0

Lưu trữ sẽ có chi phí tương tự như tìm kiếm. Và tìm kiếm nhị phân sẽ cho phép bạn tìm khe cắm nhỏ nhất có sẵn, như tôi đã nói. – shmosel

Trả lời

2

Dưới đây là một O (n) giải pháp:

Given:

List<Long> A; // size n 
List<Long> B; // size m 

Tìm 2 cạnh:

long a = Collections.max(A); // O(n) 
long b = Collections.min(B); // O(m) 

Sau đó xem nếu A lớn nhất có thể phù hợp với B nhỏ nhất:

boolean canFit = a >= b; // O(1) 

Tổng thời gian độ phức tạp O (n + m) cho n xấp xỉ bằng m là O (n).

+0

Cảm ơn con trỏ. Tuy nhiên điều này không cung cấp cho canFit một cách rất hiệu quả, tuy nhiên kể từ khi tôi cần phải biết phân vùng cũng có. –

+0

@NoviceNgười dùng bạn không nói bạn cần biết chính xác cái nào phù hợp: * Làm thế nào tôi có thể biết nếu bất kỳ giá trị Long nào từ B có giá trị nhỏ hơn bất kỳ giá trị Long nào trong A. *. – Bohemian

+0

Bạn nói đúng, xấu của tôi. Tôi nên làm rõ –

1

Bạn nên xem giao diện NavigableSet. Lưu trữ trong một tập hợp các phân vùng có sẵn với một loại khóa có kích thước. Sau đó, sử dụng toán tử ceiling để tìm phân vùng nhỏ nhất ít nhất bằng một phần mong muốn. NavigableSet cũng hỗ trợ các hoạt động addremove, tất cả những gì bạn cần để duy trì danh sách phân vùng động.

Thực hiện hợp lý NavigableSet như TreeSet cung cấp hiệu suất O (log n) cho cả ba hoạt động, trong đó n là số lượng phân vùng có sẵn. Khi bạn phân bổ một, bạn sẽ muốn loại bỏ nó và chèn lại mảnh còn lại bằng một khóa nhỏ hơn.

Cách tiếp cận khác là sử dụng một loạt các nhóm có kích thước lôgarit. Đây là những gì malloc giống như cấp phát bộ nhớ có xu hướng làm. Chúng sẽ không khớp các yêu cầu kích thước cho các khối có sẵn một cách chính xác như cách tiếp cận ở trên, nhưng chúng sẽ rất gần với thời gian không đổi. Xem phần thảo luận here để biết ví dụ về chi tiết.

+0

Cảm ơn câu trả lời của bạn. Tôi đã kết thúc bằng cách sử dụng 'TreeSet' bằng cách sử dụng so sánh tùy chỉnh của tôi. Làm việc như một say mê! –

+0

@NoviceUser Thú vị. Sử dụng đề xuất của tôi và chấp nhận một câu trả lời khác? Không quan trọng. Chỉ là lạ. – Gene

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