Lời giải tuần trước:
Lời giải
Đề bài yêu cầu tìm diện tích của ma trận vuông lớn nhất chỉ chứa số “1”. Cách đầu tiên ta có thể thử là tại mỗi ô “1”, ta mở rộng độ dài của của cạnh lên 1 đơn vị và kiểm tra xem ma trận vuông mới có chứa toàn số “1” hay không? Cách thực hiện có thể mô tả như sau:
1. Duyệt toàn bộ các ô, nếu ô chứa số “1”, ta thực hiện bước 2
2. Tăng độ dài của cạnh lên 1 đơn vị và tiến hành kiểm tra
a. Nếu ma trận vuông mới chứa toàn số “1”, ta cập nhật diện tích lớn nhất và tiếp tục bước 2 để tìm kiếm ma trận vuông lớn hơn.
b. Nếu ma trận vuông mới có chứa số “0”, ta di chuyển sang ô tiếp theo, lặp lại từ bước 1
Giải thuật trên có độ phức tạp time complexity là O(m^2 * n^2)
, với m, n là số dòng, cột của ma trận đầu vào.
Để tối ưu time complexity của bài toán này, trước hết ta cần một quan sát như sau:
- Nếu ô [i][j] hiện tại chứa số “1”, ta có thể tạo được một ma trận vuông mới bằng cách thêm nó vào 3 ma trận vuông trước đó.
- 3 ma trận vuông trước đó là các ma trận có cạnh dưới cùng bên trái (bottom right) lần lượt là: [i - 1][j], [i][j - 1], [i - 1][j - 1].
Để dễ hiểu, mời bạn đọc xem công thức sau:
Gọi L(i, j) là độ dài của ma trận vuông lớn nhất tại ô [i][j], L[i][j] được tính bằng:
L[i][j] = min{ L[i - 1][j], L[i][j - 1], L[i - 1][j - 1] } + 1
Với công thức đệ quy như trên ta có thể dễ dàng giải bài toán này theo quy hoạch động (Dynamic Programming) như sau:
https://pastebin.com/LPGizKUd
Độ phức tạp time complexity, space complexity của giải thuật là O(m*n)
.
Ta hoàn toàn có thể tối ưu space complexity của giải thuật xuống O(m)
(hoặc O(n)
), mời bạn đọc thử thực hiện.