def f(l):z=zip(l,range(len(l)));print map(sorted(z).index,z)
Hãy thử trực tuyến!
Sử dụng chỉ mục không.
Một thuật toán nhanh với một ý tưởng đơn giản. Nếu chúng ta thay vì cần phải hoán vị trong danh sách đầu vào để làm cho nó càng gần (1,2,...,n) càng tốt, chúng ta nên chỉ sắp xếp nó, như đã được chứng minh dưới đây. Kể từ khi chúng ta thay vì hoán vị (1,2,...,n) , chúng tôi chọn hoán vị đó của lệnh theo cùng một cách như danh sách đầu vào, như trong thách thức của tôi bắt chước một trật tự (trừ đầu vào có thể phải lặp đi lặp lại). (Edit: dặm chỉ ra thách thức giống hệt nhau hơn này , nơi Dennis có câu trả lời này cùng .)
Khẳng định: Một hoán vị của danh sách l giảm thiểu khoảng cách của nó tới (1,2,...,n) là l sắp xếp.
Chứng minh: Xét một số hoán vị khác l′ của l . Chúng tôi sẽ chứng minh rằng nó không thể tốt hơn l sắp xếp.
Chọn hai chỉ số i,j mà tôi' có thứ tự, đó là nơi tôi < j nhưng tôi'Tôi> l'j . Chúng tôi thấy rằng trao đổi họ không thể tăng khoảng cách đến ( 1 , 2 , . . . , N ) . Chúng tôi lưu ý rằng hoán đổi thay đổi sự đóng góp của hai yếu tố này như sau:
| tôi'Tôi- tôi | + | tôi'j- j | → | tôi'Tôi- j | + | tôi'j- tôi | .
Đây là một cách gọn gàng để cho thấy điều này không thể tăng. Hãy xem xét hai người đi trên một dãy số, một người đi từ tôi'Tôi đến Tôi và người kia từ tôi'j đến j . Tổng khoảng cách họ đi bộ là biểu thức bên trái. Vì tôi < j nhưng tôi'Tôi> l'j , họ chuyển đổi người cao hơn trên dòng số, có nghĩa là họ phải vượt qua tại một số điểm trong khi đi bộ, gọi nó là p . Nhưng khi họ đạt đến p, sau đó họ có thể trao đổi điểm đến của mình và đi bộ cùng một khoảng cách. Và sau đó, không thể tệ hơn khi họ đi bộ đến các điểm đến đã hoán đổi của họ ngay từ đầu thay vì sử dụng p làm điểm tham chiếu, điều này mang lại tổng khoảng cách ở phía bên tay phải.
Vì vậy, phân loại hai out-of-trật tự các yếu tố trong tôi' làm cho khoảng cách của nó tới ( 1 , 2 , . . . , N ) nhỏ hơn hoặc giống nhau. Lặp đi lặp lại quá trình này sẽ sắp xếp tôi cuối cùng. Vì vậy, tôi sắp xếp ít nhất là tốt như tôi' cho bất kỳ lựa chọn nào của tôi' , có nghĩa là nó là tối ưu hoặc gắn cho tối ưu.
Lưu ý rằng tài sản duy nhất của ( 1 , 2 , . . . , N ) mà chúng tôi sử dụng là nó sắp xếp, vì vậy cùng một thuật toán sẽ làm việc để hoán vị bất kỳ danh sách trao cho giảm thiểu khoảng cách của mình cho bất kỳ danh sách cố định.
Trong mã, mục đích duy nhất z=zip(l,range(len(l)))
là làm cho các yếu tố đầu vào trở nên khác biệt, đó là để tránh các mối quan hệ, trong khi vẫn giữ các so sánh giống nhau giữa các yếu tố không đồng đều. Nếu đầu vào chúng tôi đảm bảo không có sự lặp lại, chúng tôi có thể loại bỏ điều này và chỉ cần có lambda l:map(sorted(l).index,l)
.
v
, sẽ lớn hơn0
? Hoặc, ít nhất, không0
?