Như Ariel lưu ý , thuật toán tìm tối đa tiêu chuẩn được đưa ra dưới đây:
def find_maximum(a):
m = a[0]
for x in a:
if x > m: m = x
return m
trong thực tế sẽ làm việc mà không sửa đổi miễn là:
- bất kỳ cặp yếu tố nào cũng có thể được so sánh, và
- đầu vào được đảm bảo chứa một phần tử tối đa, tức là một phần tử lớn hơn từng cặp so với bất kỳ phần tử nào khác trong đầu vào.
(Giả định đầu tiên ở trên thực sự có thể được nới lỏng, thậm chí không cần phải sửa đổi thuật toán, miễn là chúng tôi giả định rằng phần tử tối đa có thể so sánh với mọi phần tử khác và x > y
luôn luôn sai nếu các phần tử x
và y
không thể so sánh được.)
Cụ thể, yêu cầu của bạn rằng:
[Chắc chắn] để chắc chắn về một câu trả lời, yếu tố này cần được so sánh rõ ràng với mọi yếu tố khác (vì so sánh không mang tính bắc cầu).
là không đúng theo các giả định được đưa ra ở trên. Trong thực tế, để chứng minh rằng thuật toán ở trên sẽ luôn tìm thấy phần tử tối đa, đủ để quan sát rằng:
- vì vòng lặp lặp trên tất cả các phần tử đầu vào, tại một số lần lặp
x
sẽ là phần tử tối đa;
- vì phần tử cực đại lớn hơn từng cặp so với mọi phần tử khác, nên theo sau, ở phần lặp đó,
m
sẽ là phần tử cực đại; và
- vì không có phần tử nào khác có thể được ghép đôi lớn hơn phần tử cực đại, nên phần tử theo sau
m
sẽ không thay đổi trên bất kỳ lần lặp tiếp theo nào.
Do đó, ở cuối vòng lặp, m
sẽ luôn là phần tử tối đa, nếu đầu vào chứa một.
Thi thiên Nếu đầu vào không nhất thiết phải luôn chứa một phần tử tối đa, thì việc xác minh thực tế đó thực sự sẽ yêu cầu kiểm tra câu trả lời của ứng viên đối với mọi yếu tố khác để xác minh rằng nó thực sự là tối đa. Tuy nhiên, chúng ta vẫn có thể làm điều đó trong thời gian O ( n ) sau khi chạy thuật toán tìm tối đa ở trên:
def find_maximum_if_any(a):
# step 1: find the maximum, if one exists
m = a[0]
for x in a:
if x > m: m = x
# step 2: verify that the element we found is indeed maximal
for x in a:
if x > m: return None # the input contains no maximal element
return m # yes, m is a maximal element
(Tôi giả sử ở đây rằng mối quan hệ >
là không phản xạ, tức là không có yếu tố nào có thể lớn hơn chính nó. Nếu không nhất thiết phải như vậy, thì nên so sánh x > m
ở bước 2 x ≠ m and x > m
, trong đó ≠
biểu thị so sánh nhận dạng. Hoặc chúng ta có thể áp dụng tối ưu hóa lưu ý dưới đây.)
Để chứng minh tính đúng đắn của biến thể thuật toán này, hãy xem xét hai trường hợp có thể xảy ra:
- Nếu đầu vào chứa một phần tử tối đa, thì bước 1 sẽ tìm thấy nó (như được hiển thị ở trên) và bước 2 sẽ xác nhận nó.
- Nếu đầu vào không chứa phần tử tối đa, thì bước 1 sẽ chọn một số phần tử tùy ý là
m
. Không quan trọng đó là yếu tố nào, vì trong mọi trường hợp, nó sẽ không tối đa, và do đó bước 2 sẽ phát hiện ra và trả về None
.
Nếu chúng ta lưu trữ các chỉ số m
trong mảng đầu vào a
, chúng ta có thể thực sự bước tối ưu hóa 2 để chỉ kiểm tra những yếu tố mà đến trước m
trong a
, vì bất kỳ yếu tố sau đã được so sánh với m
ở bước 1. Nhưng tối ưu hóa này không làm thay đổi mức độ phức tạp thời gian tiệm cận của thuật toán, vẫn là O ( n ).