Thuật toán: Làm thế nào để tôi tổng hợp O (n) và O (nlog (n)) với nhau?


22

Tôi có thuật toán theo sau để tìm các bản sao và loại bỏ chúng:

public static int numDuplicatesB(int[] arr) {
    Sort.mergesort(arr);
    int numDups = 0;
    for (int i = 1; i < arr.length; i++) {
        if (arr[i] == arr[i - 1]) {
            numDups++;
} }
    return numDups;
}

Tôi đang cố gắng tìm ra sự phức tạp thời gian trường hợp xấu nhất của điều này. Tôi biết sự hợp nhất là nlog(n)và trong vòng lặp for của tôi, tôi đang lặp lại toàn bộ tập dữ liệu để được tính là n. Tôi không chắc phải làm gì với những con số này mặc dù. Tôi có nên tổng hợp chúng lại với nhau? Nếu tôi làm điều đó, tôi sẽ làm thế nào?


1
Lưu ý bên lề: bạn có thể sử dụng bảng băm để thực hiện điều này trong O (n) tùy thuộc vào yêu cầu bộ nhớ.
corsiKa

Câu trả lời:


67
O(n) + O(n log(n)) = O(n log(n))

Đối với sự phức tạp của Big O, tất cả những gì bạn quan tâm là thuật ngữ chi phối. n log(n)thống trị nvì vậy đó là thuật ngữ duy nhất mà bạn quan tâm.


4
Một cách khác để suy nghĩ về điều này là tưởng tượng quá trình xử lý O (n) của bạn thực sự là O (n log n), như thể bạn đã thực hiện hai loại độc lập. Sau đó, bạn sẽ có 2 * O (n log n). Nhưng các hằng số tắt, vì vậy bạn quay lại O (n log n).
Jonathan Eunice

4
@Jonathan Mặc dù nó hoạt động trong thực tế, nhưng rất đúng là O (n) không bằng O (n log (n)), vì vậy tôi không khuyên bạn nên sử dụng nó một cách thường xuyên.
Aza

17
@Emrakul thực sự tôi nghĩ rằng lý luận là lý thuyết cũng như thực tế. O (n) là tập con đúng của O (n log (n)). Vì vậy, nếu f (n) thuộc về O (n) thì nó cũng thuộc về O (n log (n)).
emory

17
Cần lưu ý rằng khi chúng ta nói f(n) is O(g(n))những gì chúng ta thực sự nói là chức năng f is a member of the set of functions that grows at the rate of at most g(n) over the long term. Điều này có nghĩa là tất cả các thành viên O(n)cũng là thành viên của O(n*log(n)). Các +biểu thức như O(f(n)) + O(g(n))thực sự đề cập đến tập hợp (mà bạn thực sự có tính mô phạm, bạn thực sự nên sử dụng).
Lie Ryan

3
@LieRyan Ban đầu, nó không được đặt union, nhưng set sum : A + B = { a + b | a in A, b in B }. Điều này xảy ra là đối với các tập hợp của biểu mẫu O(g(n))này giống như tập hợp tập hợp, vì một trong các tập hợp này luôn là tập con của tập hợp kia và cả hai đều bất biến thành tổng (tức là A + A = A). (Rất tiếc, Nate đã viết về cơ bản giống nhau).
Paŭlo Ebermann

56

Hãy lý do theo cách của chúng tôi thông qua nó và nhớ định nghĩa của O. Cái tôi sẽ sử dụng là cho giới hạn ở vô cực.

Bạn đã đúng khi tuyên bố rằng bạn thực hiện hai thao tác với giới hạn tiệm cận tương ứng O(n)O(nlog(n))nhưng kết hợp chúng thành một ràng buộc không đơn giản như thêm hai hàm. Bạn biết chức năng của bạn mất ít nhất O(n)thời gian và ít nhất là O(nlog(n))thời gian. Vì vậy, thực sự lớp phức tạp cho chức năng của bạn là sự kết hợp của O(n)O(nlog(n))nhưng O(nlog(n))là một siêu khối của O(n)vì vậy thực sự nó là như vậy O(nlog(n)).


12
+1 đây sẽ là câu trả lời. Nó mô tả câu trả lời chính xác hơn bằng cách sử dụng thuật ngữ compsci.

5

Nếu bạn định đặt nó ra từ lâu thì nó sẽ trông giống như thế này:

Giả sử tổng thời gian là: an + bn log (n), trong đó a và b là hằng số (bỏ qua các điều khoản bậc thấp hơn).

Khi n đi đến vô cùng (an + bn log (n)) / n log (n) -> a / log (n) + b -> b

Vậy tổng thời gian là O (bn log (n)) = O (n log (n)).


2

Bắt đầu với định nghĩa của O ():

O (n log n) có nghĩa là "nhỏ hơn C n log n, nếu n lớn".

O (n) có nghĩa là "nhỏ hơn D n, nếu n lớn".

Nếu bạn thêm cả hai, kết quả nhỏ hơn C n log n + D n <C n log n + D n log n <(C + D) n log n = O (n log n).

Nói chung, nếu f (n)> C g (n) cho n lớn và một số C> 0, thì O (f (n)) + O (g (n)) = O (f (n)). Và sau khi thực hiện một vài trường hợp sử dụng định nghĩa của O (), bạn sẽ biết những gì bạn có thể và không thể làm.


1

Ký hiệu O lớn được định nghĩa là một tập hợp:

nhập mô tả hình ảnh ở đây

Vì vậy, nhập mô tả hình ảnh ở đâychứa tất cả các hàm - bắt đầu từ một số điểm lớn tùy ý nhập mô tả hình ảnh ở đây- luôn nhỏ hơn g.

Bây giờ, khi bạn có một hàm nằm trong nhập mô tả hình ảnh ở đâyvà sau đó thực thi một hàm khác tăng chậm hơn g thì chắc chắn là tăng chậm hơn 2g. Vì vậy, thực thi bất cứ điều gì chậm hơn g sẽ không thay đổi lớp phức tạp.

Chính thức hơn:

f, h \ in \ mathcal {O} (g) \ Rightarrow (f + h) \ in \ mathcal {O} (g)

Bạn có thể dễ dàng chứng minh điều đó.

TL; DR

Nó vẫn còn n log (n)

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.