Bạn chỉ có thể đếm số lượng đảo ngược trong danh sách.
Nghịch đảo
Một nghịch đảo trong một chuỗi các phần tử loại T
là một cặp các phần tử trình tự xuất hiện không theo thứ tự theo một số thứ tự <
trên tập hợp của T
.
Từ Wikipedia :
Chính thức, hãy A(1), A(2), ..., A(n)
là một chuỗi các n
số.
Nếu i < j
và A(i) > A(j)
, sau đó cặp (i,j)
được gọi là đảo ngược của A
.
Các số nghịch đảo của một chuỗi là một trong những biện pháp phổ biến của sortedness của nó.
Chính thức, số đảo ngược được định nghĩa là số lượng đảo ngược, nghĩa là,
Để làm cho các định nghĩa rõ ràng hơn, hãy xem xét trình tự ví dụ 9, 5, 7, 6
. Trình tự này có các nghịch đảo (0,1), (0,2), (0,3), (2,3)
và số đảo ngược 4
.
Nếu bạn muốn một giá trị giữa 0
và 1
, bạn có thể chia số đảo ngược cho N choose 2
.
Để thực sự tạo ra một thuật toán để tính điểm này cho cách sắp xếp danh sách, bạn có hai cách tiếp cận:
Cách tiếp cận 1 (Xác định)
Sửa đổi thuật toán sắp xếp yêu thích của bạn để theo dõi xem có bao nhiêu nghịch đảo khi nó chạy. Mặc dù điều này là không cần thiết và có các triển khai khác nhau tùy thuộc vào thuật toán sắp xếp bạn chọn, nhưng bạn sẽ kết thúc với một thuật toán không đắt hơn (về độ phức tạp) so với thuật toán sắp xếp bạn đã bắt đầu.
Nếu bạn đi theo con đường này, hãy lưu ý rằng nó không đơn giản như đếm "hoán đổi". Mergesort, ví dụ, là trường hợp xấu nhất O(N log N)
, nhưng nếu nó được chạy trên một danh sách được sắp xếp theo thứ tự giảm dần, nó sẽ sửa tất cả các N choose 2
nghịch đảo. Đó là O(N^2)
sự đảo ngược được sửa chữa trong O(N log N)
hoạt động. Vì vậy, một số thao tác chắc chắn phải được sửa nhiều hơn một lần đảo ngược tại một thời điểm. Bạn phải cẩn thận với việc thực hiện của bạn. Lưu ý: bạn có thể làm điều này với O(N log N)
sự phức tạp, nó chỉ là khó khăn.
Liên quan: tính toán số lần đảo ngược của người Viking trong một hoán vị
Cách tiếp cận 2 (Stochastic)
- Các cặp mẫu ngẫu nhiên
(i,j)
, trong đói != j
- Đối với mỗi cặp, xác định xem
list[min(i,j)] < list[max(i,j)]
(0 hoặc 1)
- Tính trung bình của các so sánh này và sau đó bình thường hóa bằng
N choose 2
Cá nhân tôi sẽ đi theo phương pháp ngẫu nhiên trừ khi bạn có yêu cầu về tính chính xác - nếu chỉ vì nó rất dễ thực hiện.
Nếu thứ bạn thực sự muốn là một giá trị ( z'
) nằm giữa -1
(được sắp xếp giảm dần) đến 1
(được sắp xếp tăng dần), bạn có thể chỉ cần ánh xạ giá trị ở trên ( z
), nằm giữa 0
(sắp xếp tăng dần) và 1
(sắp xếp giảm dần), cho phạm vi này bằng công thức này :
z' = -2 * z + 1