列表

详情


2713. 矩阵中严格递增的单元格数

给你一个下标从 1 开始、大小为 m x n 的整数矩阵 mat,你可以选择任一单元格作为 起始单元格

从起始单元格出发,你可以移动到 同一行或同一列 中的任何其他单元格,但前提是目标单元格的值 严格大于 当前单元格的值。

你可以多次重复这一过程,从一个单元格移动到另一个单元格,直到无法再进行任何移动。

请你找出从某个单元开始访问矩阵所能访问的 单元格的最大数量

返回一个表示可访问单元格最大数量的整数。

 

示例 1:

输入:mat = [[3,1],[3,4]]
输出:2
解释:上图展示了从第 1 行、第 2 列的单元格开始,可以访问 2 个单元格。可以证明,无论从哪个单元格开始,最多只能访问 2 个单元格,因此答案是 2 。 

示例 2:

输入:mat = [[1,1],[1,1]]
输出:1
解释:由于目标单元格必须严格大于当前单元格,在本示例中只能访问 1 个单元格。 

示例 3:

输入:mat = [[3,1,6],[-9,5,7]]
输出:4
解释:上图展示了从第 2 行、第 1 列的单元格开始,可以访问 4 个单元格。可以证明,无论从哪个单元格开始,最多只能访问 4 个单元格,因此答案是 4 。  

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int maxIncreasingCells(vector<vector<int>>& mat) { } };

rust 解法, 执行用时: 227 ms, 内存消耗: 22.5 MB, 提交时间: 2024-06-19 07:24:04

use std::collections::HashMap;

impl Solution {
    pub fn max_increasing_cells(mat: Vec<Vec<i32>>) -> i32 {
        let m = mat.len();
        let n = mat[0].len();
        let mut mp: HashMap<i32, Vec<(usize, usize)>> = HashMap::new();
        let mut row = vec![0; m];
        let mut col = vec![0; n];

        for i in 0..m {
            for j in 0..n {
                mp.entry(mat[i][j]).or_insert(Vec::new()).push((i, j));
            }
        }
        let mut sorted_map: Vec<_> = mp.iter().collect();
        sorted_map.sort_by(|a, b| a.0.cmp(b.0));
        for (_, pos) in sorted_map {
            let res: Vec<_> = pos.iter().map(|&(i, j)| row[i].max(col[j]) + 1).collect(); // 存放相同数值的答案,便于后续更新 row 和 col
            for (&(i, j), &d) in pos.iter().zip(res.iter()) {
                row[i] = row[i].max(d);
                col[j] = col[j].max(d);
            }
        }
        *row.iter().max().unwrap()
    }
}

cpp 解法, 执行用时: 696 ms, 内存消耗: 230.6 MB, 提交时间: 2024-06-19 07:23:28

class Solution {
public:
    int maxIncreasingCells(vector<vector<int>>& mat) {
        int m = mat.size(), n = mat[0].size();
        map<int, vector<pair<int, int>>> g;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                g[mat[i][j]].emplace_back(i, j); // 相同元素放在同一组,统计位置
            }
        }

        vector<int> row_max(m), col_max(n);
        for (auto& [_, pos] : g) {
            vector<int> mx; // 先把最大值算出来,再更新 row_max 和 col_max
            for (auto& [i, j] : pos) {
                mx.push_back(max(row_max[i], col_max[j]) + 1);
            }
            for (int k = 0; k < pos.size(); k++) {
                auto& [i, j] = pos[k];
                row_max[i] = max(row_max[i], mx[k]); // 更新第 i 行的最大 f 值
                col_max[j] = max(col_max[j], mx[k]); // 更新第 j 列的最大 f 值
            }
        }
        return ranges::max(row_max);
    }
};

golang 解法, 执行用时: 544 ms, 内存消耗: 30.9 MB, 提交时间: 2023-05-31 15:26:00

func maxIncreasingCells(mat [][]int) (ans int) {
	type pair struct{ x, y int }
	g := map[int][]pair{}
	for i, row := range mat {
		for j, x := range row {
			g[x] = append(g[x], pair{i, j}) // 相同元素放在同一组,统计位置
		}
	}
	a := make([]int, 0, len(g))
	for k := range g {
		a = append(a, k)
	}
	sort.Ints(a) // 从小到大

	rowMax := make([]int, len(mat))
	colMax := make([]int, len(mat[0]))
	for _, x := range a {
		pos := g[x]
		mx := make([]int, len(pos))
		for i, p := range pos {
			mx[i] = max(rowMax[p.x], colMax[p.y]) + 1 // 先把最大值算出来,再更新 rowMax 和 colMax
			ans = max(ans, mx[i])
		}
		for i, p := range pos {
			rowMax[p.x] = max(rowMax[p.x], mx[i]) // 更新第 p.x 行的最大 f 值
			colMax[p.y] = max(colMax[p.y], mx[i]) // 更新第 p.y 列的最大 f 值
		}
	}
	return
}

func max(a, b int) int { if b > a { return b }; return a }

java 解法, 执行用时: 186 ms, 内存消耗: 89.1 MB, 提交时间: 2023-05-31 15:25:41

class Solution {
    public int maxIncreasingCells(int[][] mat) {
        var g = new TreeMap<Integer, List<int[]>>();
        int m = mat.length, n = mat[0].length;
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                // 相同元素放在同一组,统计位置
                g.computeIfAbsent(mat[i][j], k -> new ArrayList<>()).add(new int[]{i, j});

        int ans = 0;
        int[] rowMax = new int[m], colMax = new int[n];
        for (var pos : g.values()) {
            var mx = new int[pos.size()];  // 先把最大值算出来,再更新 rowMax 和 colMax
            for (int i = 0; i < pos.size(); i++) {
                mx[i] = Math.max(rowMax[pos.get(i)[0]], colMax[pos.get(i)[1]]) + 1;
                ans = Math.max(ans, mx[i]);
            }
            for (int k = 0; k < pos.size(); k++) {
                int i = pos.get(k)[0], j = pos.get(k)[1];
                rowMax[i] = Math.max(rowMax[i], mx[k]); // 更新第 i 行的最大 f 值
                colMax[j] = Math.max(colMax[j], mx[k]); // 更新第 j 列的最大 f 值
            }
        }
        return ans;
    }
}

python3 解法, 执行用时: 1232 ms, 内存消耗: 71.3 MB, 提交时间: 2023-05-31 15:25:19

'''
动态规划
f[i][j]表示到达mat[i][j]时所访问的单元格的最大数量
'''
class Solution:
    def maxIncreasingCells(self, mat: List[List[int]]) -> int:
        g = defaultdict(list)
        for i, row in enumerate(mat):
            for j, x in enumerate(row):
                g[x].append((i, j))  # 相同元素放在同一组,统计位置

        ans = 0
        row_max = [0] * len(mat)
        col_max = [0] * len(mat[0])
        for _, pos in sorted(g.items(), key=lambda p: p[0]):
            # 先把最大值算出来,再更新 row_max 和 col_max
            mx = [max(row_max[i], col_max[j]) + 1 for i, j in pos]
            ans = max(ans, max(mx))
            for (i, j), f in zip(pos, mx):
                row_max[i] = max(row_max[i], f)  # 更新第 i 行的最大 f 值
                col_max[j] = max(col_max[j], f)  # 更新第 j 列的最大 f 值
        return ans

上一题