Tôi phải sắp xếp một danh sách các số, nhưng tôi siêu lười. Thật sự rất khó để tìm ra cách hoán đổi tất cả các số xung quanh cho đến khi tất cả chúng theo thứ tự tăng dần, vì vậy tôi đã đưa ra thuật toán của riêng mình để đảm bảo rằng danh sách mới được sắp xếp¹. Đây là cách nó hoạt động:
Để có danh sách kích thước N , chúng ta sẽ cần các lần lặp N-1 . Trên mỗi lần lặp lại,
Kiểm tra xem số thứ N có nhỏ hơn số thứ N + 1 không . Nếu có, thì hai số này đã được sắp xếp và chúng ta có thể bỏ qua phép lặp này.
Nếu chúng không phải, thì bạn cần liên tục giảm các số N đầu tiên cho đến khi hai số này theo thứ tự.
Hãy lấy một ví dụ cụ thể. Giả sử đầu vào là
10 5 7 6 1
Ở lần lặp đầu tiên, chúng ta sẽ so sánh 10 và 5. 10 lớn hơn 5, vì vậy chúng tôi giảm dần cho đến khi nó nhỏ hơn:
4 5 7 6 1
Bây giờ chúng ta so sánh 5 và 7. 5 nhỏ hơn 7, vì vậy chúng ta không cần phải làm gì với phép lặp này. Vì vậy, chúng tôi đi đến phần tiếp theo và so sánh 7 và 6. 7 lớn hơn 6, vì vậy chúng tôi giảm ba số đầu tiên cho đến khi nó nhỏ hơn 6 và chúng tôi nhận được điều này:
2 3 5 6 1
Bây giờ chúng tôi so sánh 6 và 1. Một lần nữa, 6 lớn hơn 1, vì vậy chúng tôi giảm bốn số đầu tiên cho đến khi nó nhỏ hơn 1 và chúng tôi nhận được điều này:
-4 -3 -1 0 1
Và chúng ta đã hoàn thành! Bây giờ danh sách của chúng tôi là theo thứ tự hoàn hảo sắp xếp. Và, để làm cho mọi thứ trở nên tốt hơn, chúng tôi chỉ phải lặp qua danh sách N-1 lần, vì vậy thuật toán này sắp xếp danh sách theo thời gian O (N-1) , mà tôi khá chắc chắn là thuật toán nhanh nhất có .²
Thách thức của bạn cho ngày hôm nay là thực hiện Lazy Sort này. Chương trình hoặc chức năng của bạn sẽ được cung cấp một loạt các số nguyên ở bất kỳ định dạng chuẩn nào bạn thích và bạn phải thực hiện loại sắp xếp lười biếng này và trả về danh sách "đã sắp xếp" mới . Mảng sẽ không bao giờ trống hoặc chứa các số nguyên.
Dưới đây là một số ví dụ:
Input: 10 5 7 6 1
Output: -4 -3 -1 0 1
Input: 3 2 1
Output: -1 0 1
Input: 1 2 3
Output: 1 2 3
Input: 19
Output: 19
Input: 1 1 1 1 1 1 1 1 1
Output: -7 -6 -5 -4 -3 -2 -1 0 1
Input: 5 7 11 6 16 2 9 16 6 16
Output: -27 -25 -21 -20 -10 -9 -2 5 6 16
Input: -8 17 9 7
Output: -20 5 6 7
Như mọi khi, đây là môn đánh gôn , vì vậy hãy viết chương trình ngắn nhất bạn có thể!
¹ này không có nghĩa là những gì có vẻ như nó có nghĩa, nhưng nó là về mặt kỹ thuật đúng
² Tôi hoàn toàn đùa, xin đừng ghét tôi
<sarcasm>
Thuật toán sắp xếp này thực sự vẫn đồng hồ ở mức O(N^2)
độ phức tạp vì bạn phải đi qua tất cả các mục được truy cập trước đó trong danh sách để giảm chúng. Tôi khuyên bạn nên đi qua danh sách ngược thay vào đó và chỉ giảm một số cho mỗi bước khi cần thiết. Điều này sẽ cung cấp cho bạn sự O(N)
phức tạp thực sự! </sarcasm>
O(n^2)
về quyền truy cập bộ nhớ, nhưng không phải là O(n)
để so sánh?
O(N^2)
.