Viết chương trình (hoặc hàm) thể hiện bốn độ phức tạp thời gian O lớn phổ biến tùy thuộc vào cách nó được chạy. Trong bất kỳ hình thức nào, nó có một số nguyên dương N mà bạn có thể giả sử là ít hơn 2 31 .
Khi chương trình được chạy ở dạng ban đầu, nó sẽ có độ phức tạp không đổi . Đó là, độ phức tạp phải là Θ (1) hoặc tương đương, Θ (1 ^ N) .
Khi chương trình được đảo ngược và chạy nó sẽ có độ phức tạp tuyến tính . Nghĩa là, độ phức tạp phải là Θ (N) hoặc, tương đương, Θ (N ^ 1) .
(Điều này có ý nghĩa vìN^1được1^Nđảo ngược.)Khi chương trình được tăng lên gấp đôi , tức là nối với chính nó, và chạy nó nên có mũ phức tạp, đặc biệt là 2 N . Đó là, độ phức tạp phải là Θ (2 ^ N) .
(Điều này có ý nghĩa vì2in2^Nlà gấp đôi1in1^N.)Khi chương trình được nhân đôi và đảo ngược và chạy, nó sẽ có độ phức tạp đa thức , cụ thể là N 2 . Đó là, độ phức tạp phải là Θ (N ^ 2) .
(Điều này có ý nghĩa vìN^2được2^Nđảo ngược.)
Bốn trường hợp này là những trường hợp duy nhất bạn cần xử lý.
Lưu ý rằng để chính xác, tôi đang sử dụng ký hiệu theta () lớn thay vì chữ O lớn vì thời gian chạy của các chương trình của bạn phải được giới hạn ở cả trên và dưới bởi độ phức tạp bắt buộc. Nếu không, chỉ cần viết một hàm trong O (1) sẽ thỏa mãn cả bốn điểm. Nó không quá quan trọng để hiểu sắc thái ở đây. Chủ yếu, nếu chương trình của bạn đang thực hiện các hoạt động k * f (N) cho một số k không đổi thì có khả năng là trong (f (N)).
Thí dụ
Nếu chương trình ban đầu là
ABCDEsau đó chạy nó sẽ mất thời gian liên tục. Đó là, cho dù đầu vào N là 1 hoặc 2147483647 (2 31 -1) hoặc bất kỳ giá trị nào ở giữa, nó sẽ chấm dứt trong khoảng thời gian gần như nhau.
Phiên bản đảo ngược của chương trình
EDCBAnên mất thời gian tuyến tính theo N. Đó là thời gian cần thiết để chấm dứt tỷ lệ xấp xỉ với N. Vì vậy, N = 1 mất ít thời gian nhất và N = 2147483647 mất nhiều thời gian nhất.
Phiên bản nhân đôi của chương trình
ABCDEABCDEnên mất hai-to-the-N lần về N. Đó là, thời gian cần thiết để chấm dứt nên xấp xỉ tỉ lệ với 2 N . Vì vậy, nếu N = 1 chấm dứt trong khoảng một giây, N = 60 sẽ mất nhiều thời gian hơn tuổi của vũ trụ để chấm dứt. (Không, bạn không phải kiểm tra nó.)
Phiên bản nhân đôi và đảo ngược của chương trình
EDCBAEDCBAnên mất thời gian bình phương về mặt N. Đó là, thời gian cần thiết để chấm dứt nên tỷ lệ thuận với N * N. Vì vậy, nếu N = 1 chấm dứt trong khoảng một giây, N = 60 sẽ mất khoảng một giờ để chấm dứt.
Chi tiết
Bạn cần thể hiện hoặc lập luận rằng các chương trình của bạn đang chạy trong sự phức tạp mà bạn nói chúng là. Đưa ra một số dữ liệu thời gian là một ý tưởng tốt nhưng cũng cố gắng giải thích tại sao về mặt lý thuyết sự phức tạp là chính xác.
Thật tốt nếu trong thực tế thời gian các chương trình của bạn không đại diện hoàn hảo cho sự phức tạp của chúng (hoặc thậm chí là xác định). ví dụ: đầu vào N + 1 đôi khi có thể chạy nhanh hơn N.
Môi trường bạn đang chạy chương trình của bạn có vấn đề. Bạn có thể đưa ra các giả định cơ bản về cách các ngôn ngữ phổ biến không bao giờ cố tình lãng phí thời gian trong các thuật toán, nhưng, ví dụ, nếu bạn biết phiên bản cụ thể của Java thực hiện sắp xếp bong bóng thay vì thuật toán sắp xếp nhanh hơn , thì bạn nên tính đến điều đó nếu bạn thực hiện bất kỳ sắp xếp nào .
Đối với tất cả các phức tạp ở đây giả sử chúng ta đang nói về các tình huống xấu nhất , không phải trường hợp tốt nhất hoặc trường hợp trung bình.
Độ phức tạp không gian của các chương trình không quan trọng, chỉ có độ phức tạp thời gian.
Các chương trình có thể xuất ra bất cứ điều gì. Nó chỉ là vấn đề mà họ lấy số nguyên dương N và có độ phức tạp thời gian chính xác.
Bình luận và các chương trình multiline được cho phép. (Bạn có thể cho rằng
\r\nđảo ngược là\r\nđể tương thích với Windows.)
Nhắc nhở Big O
Từ nhanh nhất đến chậm nhất O(1), O(N), O(N^2), O(2^N)(thứ tự 1, 2, 4, 3 ở trên).
Điều khoản chậm hơn luôn chiếm ưu thế, ví dụ O(2^N + N^2 + N) = O(2^N).
O(k*f(N)) = O(f(N))cho hằng số k. Vì vậy O(2) = O(30) = O(1)và O(2*N) = O(0.1*N) = O(N).
Ghi nhớ O(N^2) != O(N^3)và O(2^N) != O(3^N).
Chấm điểm
Đây là mã golf bình thường. Chương trình gốc ngắn nhất (thời gian không đổi một) tính bằng byte thắng.
n = input(); for i in xrange(n): passcó độ phức tạp theo cấp số nhân, bởi vì nó thực 2 ** khiện các bước, k = log_2(n)kích thước đầu vào ở đâu. Bạn nên làm rõ liệu đây là trường hợp, vì nó thay đổi đáng kể các yêu cầu.