Maximum Strictly Increasing Cells in a Matrix
Maximum Strictly Increasing Cells in a Matrix
Given a 1-indexed m x n integer matrix mat, you can select any cell in the matrix as your starting cell.
From the starting cell, you can move to any other cell in the same row or column, but only if the value of the destination cell is strictly greater than the value of the current cell. You can repeat this process as many times as possible, moving from cell to cell until you can no longer make any moves.
Your task is to find the maximum number of cells that you can visit in the matrix by starting from some cell.
Return an integer denoting the maximum number of cells that can be visited.
Example 1:
Input: mat = [[3,1],[3,4]] Output: 2 Explanation: The image shows how we can visit 2 cells starting from row 1, column 2. It can be shown that we cannot visit more than 2 cells no matter where we start from, so the answer is 2.
Example 2:
Input: mat = [[1,1],[1,1]] Output: 1 Explanation: Since the cells must be strictly increasing, we can only visit one cell in this example.
Example 3:
Input: mat = [[3,1,6],[-9,5,7]] Output: 4 Explanation: The image above shows how we can visit 4 cells starting from row 2, column 1. It can be shown that we cannot visit more than 4 cells no matter where we start from, so the answer is 4.
Constraints:
- m == mat.length
- n == mat[i].length
- 1 <= m, n <= 105
- 1 <= m * n <= 105
- -105 <= mat[i][j] <= 105
解题思路
首先很容易想到记忆化搜索。记当前格子的数值为,那么我们可以转移到同一行中比严格大的格子,或者同一列中比严格大的格子。可以发现整个转移的过程格子的数值不断增大,因此不可能转移到之前访问过的格子,即(转移)图中不会存在环,所以可以用动态规划来求解。
定义状态表示所有从出发能转移到的格子所构成路径的集合,属性是路径长度的最大值。
对于当前的格子,如果直接暴力枚举可以转移到的格子,那么转移的时间复杂度为,由于一共有个状态,因此整个记忆化搜索的时间复杂度就是,会超时。
对于当前的格子无非就是要找到第行和第列中所有严格大于的格子,然后再从转移。可以发现在这个过程中数值小于等于的格子完全不用考虑,永远只考虑数值严格大于的格子,并且随着转移的次数越多,数值越大。因此想到能不能对矩阵中的格子按照数值从大到小排序,然后再按照数值从大到小来记忆化搜索,同时开一个数组表示第行中已搜索过格子的的最大值,表示第列中已搜索过格子的的最大值。因此当需要搜索格子时,因为只需考虑第行和第列中严格大于的格子,而这些格子之前已经搜索过了,并且在第行中能转移到的最多格子为,在第列中能转移到的最多格子为,因此就有。然后更新,。可以发现整个过程直接枚举求解即可,不需要用到递归搜索。
需要注意的是如果在排序后存在连续的数值相同的格子,即,那么我们需要把这些格子都找出来同时处理。否则某一行或某一列的和会被值相同的格子的更新,当再枚举到值相同且在同一行或同一列的格子时,可能就会被之前枚举过的值相同的格子更新,即转移到值相同的格子,这就出问题了。
AC代码如下,时间复杂度为:
1 class Solution { 2 public: 3 int maxIncreasingCells(vector<vector<int>>& mat) { 4 int n = mat.size(), m = mat[0].size(); 5 vector<vector<int>> p; 6 for (int i = 0; i < n; i++) { 7 for (int j = 0; j < m; j++) { 8 p.push_back({mat[i][j], i, j}); 9 } 10 } 11 sort(p.begin(), p.end(), greater<vector<int>>()); 12 vector<vector<int>> f(n, vector<int>(m)); 13 vector<int> r(n), c(m); 14 for (int i = 0; i < p.size(); i++) { 15 int j = i; 16 while (j < p.size() && p[j][0] == p[i][0]) { 17 j++; 18 } 19 for (int k = i; k < j; k++) { 20 f[p[k][1]][p[k][2]] = max(r[p[k][1]], c[p[k][2]]) + 1; 21 } 22 for (int k = i; k < j; k++) { 23 r[p[k][1]] = max(r[p[k][1]], f[p[k][1]][p[k][2]]); 24 c[p[k][2]] = max(c[p[k][2]], f[p[k][1]][p[k][2]]); 25 } 26 i = j - 1; 27 } 28 int ret = 0; 29 for (int i = 0; i < n; i++) { 30 for (int j = 0; j < m; j++) { 31 ret = max(ret, f[i][j]); 32 } 33 } 34 return ret; 35 } 36 };
参考资料
动态规划+优化【力扣周赛 347】:https://www.bilibili.com/BV1fo4y1T7MQ/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17452087.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效