You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
***Giải thuật quay lùi** - tương tự brute force ta cũng tìm tất cả các khả năng nhưng trong quá trình tìm kiếm, nếu ta gặp một hướng lựa chọn không thỏa mãn, ta quay lui về điểm lựa chọn nơi có các hướng khác và thử hướng lựa chọn tiếp theo. Khi đã thử hết các lựa chọn xuất phát từ điểm lựa chọn đó, ta quay lại điểm lựa chọn trước đó và thử hướng lựa chọn tiếp theo tại đó. Quá trình tìm kiếm thất bại khi không còn điểm lựa chọn nào nữa
***Giải thuật nhánh cận** - ghi nhớ giải pháp chi phí thấp nhất được tìm thấy ở mỗi giai đoạn của tìm kiếm quay lùi, và sử dụng chi phí của giải pháp chi phí thấp nhất được tìm thấy như là một ràng buộc thấp hơn về chi phí của một giải pháp chi phí thấp nhất cho vấn đề, để loại bỏ các giải pháp với chi phí lớn hơn giải pháp chi phí thấp nhất được tìm thấy cho đến nay.
Cho một mảng số nguyên không âm biểu diễn các bậc thang trong bản đồ độ cao trong đó chiều rộng mỗi bậc là `1` đơn vị, hãy tính lượng nước còn lại trong thềm sau khi mưa.
Đọng "1" đơn vị giữa bậc 1 và 2, "4" đơn vị giữa bậc 2 và 3, và "1" đơn vị giữa 2 bậc 2.
51
+
```
52
+
53
+
## Giải thuật
54
+
55
+
Một phần tử của mảng có thể đọng nước nếu có bậc cao hơn ở bên trái và phải. Ta có thể tìm lương nước đọng trong mọi phần tử bằng cách tìm chiều cao của các bậc bên trái và phải. Ý tưởng là tính toán lượng nước có thể lưu trữ trong mọi phần tử của mảng, ví dụ ta có mảng `[3, 0, 0, 2, 0, 4]`, ta có thể đọng "3*2" đơn vị giữa bậc 3 và 3, "1" đơn vị trên đỉnh bậc 2 và "3" đơn vị giữa 2 và 4. Xem sơ đồ dưới đây.
56
+
57
+
58
+
### Giải pháp 1: Phá mã
59
+
60
+
Với từng phần tử trong mảng, ta tìm lượng nước lớn nhất có thể đọng sau mưa, bằng mức tối thiểu của chiều cao tối đa của các bậc ở cả hai bên trừ đi chiều cao của chính nó.
61
+
62
+
**Bước**
63
+
64
+
- Khởi tạo `answer = 0`
65
+
- Lặp lại từ trái sang phải mảng:
66
+
- Khởi tạo `max_left = 0` và `max_right = 0`
67
+
- Lặp lại từ phần tử hiện tại đến khi phần bắt đầu thay đổi của mảng: `max_left = max(max_left, height[j])`
68
+
- Lặp lại từ phần tử hiện tại đến phần kết thúc thay đổi của mảng: `max_right = max(max_right, height[j])`
69
+
- Thêm `min(max_left, max_right) - height[i]` vào `answer`
70
+
71
+
**Phân tích độ phức tạp**
72
+
73
+
Độ phức tạp thời gian: `O(n^2)`. Với từng phần tử, ta phải lặp phần bên trái và bên phải.
74
+
75
+
Độ phức tạp không gian mở rộng: `O(1)` không gian mở rộng
76
+
77
+
### Giải pháp 2: Quy hoạch động
78
+
79
+
Với giải pháp phá mã, ta phải lặp từ bên trái và bên phải mỗi lần để tìm ra bậc cao nhất tính đến chỉ số đó. Nhưng ta có thể lưu trữ chúng với quy hoạch động.
80
+
81
+
Với quy hoạch động ta có thể tính toán trước bậc cao nhất ở bên trái và bên phải của mọi bậc trong thời gian `O (n)`. Sau đó, sử dụng các giá trị được tính toán trước này để tìm lượng nước trong mọi phần tử mảng.
- Tìm bậc cao nhất từ bên trái của chỉ số `i` trong mảng `left_max`
90
+
- Tìm bậc cao nhất từ bên phải của chỉ số `i` trong mảng `right_max`
91
+
- Lặp lại mảng `height` và cập nhật `answer`:
92
+
- Thêm `min(max_left[i], max_right[i]) - height[i]` vào `answer`.
93
+
94
+
**Phân tích độ phức tạp**
95
+
96
+
Độ phức tạp thời gian: `O(n)`. Ta lưu trữ độ cao lớn nhất đến một điểm bằng cách dùng 2 lần lặp lại `O(n)`. Cuối cùng cập nhật `answer` bằng giá trị đã lưu ở `O(n)`.
97
+
98
+
Độ phức tạp không gian: `O(n)` không gian mở rộng. Bổ sung không gian cho mảng `left_max` và `right_max` so với giải pháp 1.
0 commit comments