Tôi tin rằng tôi có thể làm điều này là O (n log n).
Đầu tiên, sắp xếp mảng B
, áp dụng cùng hoán vị cho mảng A
(và ghi nhớ hoán vị). Đây là phần O (n log n). Vì chúng ta tổng hợp trên tất cả i, việc áp dụng cùng hoán vị cho mảng A và B không thay đổi mức tối thiểu.
Với một mảng được sắp xếp B
, phần còn lại của thuật toán thực sự là O (n).
Đối với mỗi k, hãy xác định một mảng C k [i] = | B [i] - B [k] |
(Lưu ý:. Chúng tôi sẽ không thực sự xây dựng C k ... Chúng tôi sẽ chỉ cần sử dụng nó như là một khái niệm cho lập luận dễ dàng hơn)
Quan sát rằng số lượng chúng tôi đang cố gắng để giảm thiểu (trên k) là tổng của A [i] * C k [i]. Chúng ta hãy đi trước và cho rằng một cái tên:
Xác định: S k = Σ A [i] * C k [i]
Bây giờ, đối với bất kỳ k Đặc biệt, những gì hiện C k nhìn?
Vâng, C k [k] = 0, hiển nhiên.
Nhiều thú vị, vì mảng B được sắp xếp, chúng ta có thể thoát khỏi những dấu hiệu giá trị tuyệt đối:
- C k [i] = B [k] - B [i], 0 < = i < k
- C k [i] = 0, i = k
- C k [i] = B [i] - B [k], cho k < i < n
Hãy xác định hai điều nữa.
Định nghĩa: T k = Σ A [i] 0 < = i < k
Định nghĩa: U k = Σ A [i] cho k < i < n
(Tức là, T k là tổng của các thành phần k-1 đầu tiên của A. U k là tổng của tất cả trừ các phần tử k đầu tiên của A.)
Các quan sát chính: Với S k, T k, và U k, chúng ta có thể tính toán S k + 1, T k + 1, và U k + 1 trong liên tục thời gian. Làm sao?
T và U thật dễ dàng.
Câu hỏi đặt ra là, làm thế nào để chúng tôi nhận được từ S k tới S k + 1?
Hãy xem xét điều gì sẽ xảy ra với C k khi chúng tôi truy cập C k + 1. Chúng ta chỉ cần thêm B [k + 1] -B [k] vào mọi phần tử của C từ 0 đến k, và chúng ta trừ đi cùng một lượng từ mọi phần tử của C từ k + 1 đến n (chứng minh điều này). Điều đó có nghĩa là chúng ta chỉ cần thêm T k * (B [k + 1] - B [k]) và trừ U k * (B [k + 1] - B [k]) để nhận được từ S k tới S k + 1.
Đại số ... Cụm từ k đầu tiên của S k chỉ là tổng từ 0 đến k-1 của A [i] * (B [k] - B [i]).
Các điều khoản k đầu tiên của S k + 1 là tổng từ 0 đến k-1 của A [i] * (B [k + 1] - B [i])
Sự khác biệt giữa đây là tổng, từ 0 đến k-1, của (A [i] * (B [k + 1] - B [i]) - (A [i] * (B [k] - B [i])) Đưa ra các thuật ngữ A [i] và hủy các từ B [i] để lấy tổng từ 0 đến k-1 của A [i] * (B [k + 1] - B [k]), là chỉ T k * (B [k + 1] - B [k]).
Tương tự đối với các điều khoản n-k-1 cuối cùng của S k.
Kể từ khi chúng ta có thể tính toán S , T , và U trong thời gian tuyến tính, và chúng ta có thể đi từ S k S k + 1 trong thời gian liên tục, chúng tôi có thể tính toán tất cả S k trong thời gian tuyến tính. Vì vậy, làm điều đó, nhớ nhỏ nhất, và bạn đã làm xong.
Sử dụng nghịch đảo của hoán vị sắp xếp để lấy k
cho các mảng ban đầu.
@Dukeline: Tôi cho rằng anh ta chỉ có nghĩa là giá trị tuyệt đối. – Nemo