Có, nó có thể được thực hiện tốt hơn.
Trước hết, chúng ta hãy suy nghĩ về một cấu trúc dữ liệu cho phép chúng ta
- Cập nhật bất kỳ giá trị duy nhất của mảng 1D tiềm ẩn trong
O(logn)
thời gian
- Tìm tổng của subarray tối đa của mảng trong
O(1)
thời gian
Thực ra, một cây nhị phân cân bằng trông giống như dưới đây có thể thực hiện công việc. Cấu trúc cây có thể được mô tả là:
- Mỗi nút lá của cây đại diện cho mọi phần tử của mảng.
- Nếu một nút bên trong bao gồm phạm vi
[a, b]
, con trái của nó bao phủ phạm vi [a, c]
và con phải của nó bao phủ phạm vi [c + 1, b]
, trong đó c = floor((a + b)/2))
.
Nút gốc bao gồm phạm vi [1, n]
.
O
/ \
/ \
/ \
/ \
/ \
O O
/ \ / \
/ \ / \
/ \ / \
O O O O
/\ /\ /\ /\
o o o o o o o o
A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8]
Có 4 lĩnh vực gắn liền với mỗi nút v
(bao gồm cả các nút lá và các nút nội bộ):
S[v]
: tổng của tất cả các giá trị trong phạm vi v
's
M[v]
: tổng số chi tiết phụ tối đa trong phạm vi của v
của
L[v]
: tổng của maximu m subarray rằng bắt đầu từ phía bên trái của v
'phạm vi s
R[v]
: tổng của subarray tối đa mà kết thúc vào phía bên phải của v
' phạm vi s
Dựa trên các định nghĩa trên, chúng ta có thể tìm ra quy tắc cập nhật sau:
- Đối với bất kỳ nút lá
v
, S[v] = A[v]
, M[v] = L[v] = R[v] = max{0, A[v]}
- Đối với bất kỳ nút nội
v
và con của nó l
và r
,
S[v] = S[l] + S[r]
M[v] = max{M[l], M[r], R[l] + L[r]}
L[v] = max{L[l], L[r] + S[l]}
R[v] = max{R[r], R[l] + S[r]}
Cuối cùng, chúng ta có thể thực hiện các hoạt động nêu ở phần đầu.
- Để cập nhật
A[i]
, chúng tôi có thể tìm thấy nút lá tương ứng trên cây và cập nhật các trường dọc theo đường dẫn tới gốc bằng các quy tắc trên.
- Tổng chi phí con tối đa chỉ đơn giản là
M[root]
.
Bây giờ, hãy thảo luận cách tìm hình chữ nhật tối đa bằng cấu trúc dữ liệu này. Nếu chúng ta sửa hàng trên và hàng dưới của hình chữ nhật thành các hàng thứ 1, i
và j
thì vấn đề sẽ trở thành vấn đề tổng hợp subarray tối đa 1D, trong đó A[k] = sum{B[i..j, k]}
. Thông tin chi tiết chính là, đối với i
cố định, nếu chúng tôi liệt kê j
theo thứ tự tăng dần, chúng tôi có thể sử dụng cấu trúc dữ liệu ở trên để duy trì mảng 1D cơ bản và tìm câu trả lời rất nhanh. Các giả mô tả ý tưởng:
result = 0
for i in (1, 2, ..., n)
set all fields of the binary tree T to 0
for j in (i, i + 1, ..., n)
for any k where B[j, k] != 0
T.update(k, A[k] + B[j, k])
result = max{M[root], result}
return result
Giả sử ma trận chứa m
yếu tố khác không, mức độ phức tạp thời gian của thuật toán này là O(mn logn)
. Trong trường hợp của bạn m = O(n)
, do đó độ phức tạp của thời gian là O(n^2 logn)
và tốt hơn là O(n^3)
.
Nếu có nhiều giá trị khác không phải trong mỗi hàng và trong mỗi cột, sau đó chiếu các giá trị đó vào trục x và trục y, bạn sẽ nhận được hai mảng một chiều mỗi kích thước n.Tìm subarray tiếp giáp tối đa của hai mảng. Tôi nghĩ rằng điều này sẽ cho bạn hình chữ nhật tối đa. Điều này có thể được thực hiện trong O (n) thời gian và O (n) không gian phức tạp. –
Thật không may giải pháp O (n) được đề xuất này không hoạt động, như ví dụ phản đối sau đây: 1 0 0 \\ 0 0 2 \\ 0 -1 0 \\ – user2566092