3459. 最长 V 形对角线段的长度
Problem: 3459. 最长 V 形对角线段的长度
文章目录
- 思路
- 解题过程
- 复杂度
- Code
思路
记忆化搜索
解题过程
定义 dfs(i,j,k,canTurn,target) 表示在如下约束下的最长移动步数。
上一步的位置在 (i,j)。(定义成上一步,方便编程实现)
移动方向为 DIRS[k],其中 DIRS 是一个长为 4 的方向数组。
是否可以右转,用布尔值 canTurn 表示。
当前位置的目标值必须等于 target。
复杂度
- 时间复杂度: O(mn)O(mn)O(mn)
- 空间复杂度: O(mn)O(mn)O(mn)
Code
class Solution {static constexpr int DIRS[4][2] = {{1, 1}, {1, -1}, {-1, -1}, {-1, 1}};public:int lenOfVDiagonal(vector<vector<int>>& grid) {int m = grid.size(), n = grid[0].size();vector memo(m, vector<array<array<int, 2>, 4>>(n));auto dfs = [&](this auto&& dfs, int i, int j, int k, bool can_turn,int target) -> int {i += DIRS[k][0];j += DIRS[k][1];if (i < 0 || i >= m || j < 0 || j >= n || grid[i][j] != target) {return 0;}int& res = memo[i][j][k][can_turn];if (res) {return res;}res = dfs(i, j, k, can_turn, 2 - target) + 1; if (can_turn) {res = max(res, dfs(i, j, (k + 1) % 4, false, 2 - target) +1); }return res;};int ans = 0;for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (grid[i][j] == 1) {for (int k = 0; k < 4; k++) { ans = max(ans, dfs(i, j, k, true, 2) + 1);}}}}return ans;}
};