华为机考题:矩阵中的最长递增路径

题目描述

给定一个 m x n 的整数矩阵 matrix,找出其中最长递增路径的长度。

对于每个单元格,你可以往上、下、左、右四个方向移动。不能 在对角线 方向上移动,也不能 移动到边界外 ,并且不能 走重复的单元格。路径必须是严格递增的。

输入描述

  • 第一行:两个整数 m 和 n,表示矩阵的行数和列数(1 <= m, n <= 200)。

  • 接下来 m 行:每行 n 个整数,表示矩阵元素(-10^4 <= matrix[i][j] <= 10^4)。

输出描述

一个整数,表示最长递增路径的长度。

示例

输入:

text

复制代码
3 3
9 9 4
6 6 8
2 1 1

输出:

text

复制代码
4

说明: 最长递增路径为 1 -> 2 -> 6 -> 9(或 1 -> 2 -> 6 -> 8),长度为 4。


输入:

text

复制代码
1 1
5

输出:

text

复制代码
1

输入:

text

复制代码
2 3
3 4 5
3 2 6

输出:

text

复制代码
4

说明: 最长递增路径为 3 -> 4 -> 5 -> 6。


方法一:DFS + 记忆化搜索(推荐)

思路: 从每个单元格出发做 DFS,向四个方向探索,只走向比当前值大的相邻单元格。用 memo[i][j] 记录以 (i, j) 为起点的最长递增路径长度,避免重复计算。

  • 如果 memo[i][j] != 0,直接返回缓存值。

  • 否则,遍历四个方向,对满足 matrix[ni][nj] > matrix[i][j] 的邻居递归求解,取最大值 + 1。

  • 最终答案是所有单元格中的最大值。

时间复杂度 O(m * n)(每个单元格最多计算一次),空间复杂度 O(m * n)(记忆化数组 + 递归栈)。

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class Solution {
public:
    int m, n;
    vector<vector<int>> memo;
    int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

    int longestIncreasingPath(vector<vector<int>>& matrix) {
        if (matrix.empty() || matrix[0].empty()) return 0;

        m = matrix.size();
        n = matrix[0].size();
        memo.assign(m, vector<int>(n, 0));

        int ans = 0;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                ans = max(ans, dfs(matrix, i, j));
            }
        }
        return ans;
    }

private:
    int dfs(vector<vector<int>>& matrix, int i, int j) {
        if (memo[i][j] != 0) return memo[i][j];

        int best = 1; // 至少包含自己
        for (auto& d : dirs) {
            int ni = i + d[0];
            int nj = j + d[1];
            if (ni >= 0 && ni < m && nj >= 0 && nj < n &&
                matrix[ni][nj] > matrix[i][j]) {
                best = max(best, 1 + dfs(matrix, ni, nj));
            }
        }

        memo[i][j] = best;
        return best;
    }
};

int main() {
    int m, n;
    cin >> m >> n;

    vector<vector<int>> matrix(m, vector<int>(n));
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            cin >> matrix[i][j];
        }
    }

    Solution sol;
    cout << sol.longestIncreasingPath(matrix) << endl;

    return 0;
}
相关推荐
A7bert7772 小时前
【SAM3部署至AGX Orin】环境配置→模型部署→问题记录
c++·人工智能·深度学习·ubuntu
longlongzihan2 小时前
LeetCode 56合并区间:排序与贪心
c++·算法·leetcode
程序员老陆2 小时前
C++ 继承方式:公有、保护、私有,到底在控制什么
开发语言·c++
坤坤子吖2 小时前
C++11——Lambda、function、bind 与可调用对象
c++·笔记·学习
free-elcmacom2 小时前
手撕 memcpy 和 memmove:从字节级拷贝到内存重叠的终极较量
c语言·开发语言·青少年编程·visual studio code·visual studio
程序员_小兵2 小时前
PCIe Switch Fabric 技术解析
服务器·c语言·嵌入式硬件·php·fabric
白杨尚青2 小时前
C++入门篇(十一):string(中)——容量与增删改查:一篇吃透所有常用接口(万字详解)
java·开发语言·c++
朔北之忘 Clancy2 小时前
2024 CSP-J 第二轮真题解析
c++·算法·青少年编程·noip·csp·信奥赛·noi