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

题目描述

给定一个 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;
}
相关推荐
不会就选b2 小时前
C++补充部分(一)--lambda 表达式
开发语言·c++
丰色木夕9 小时前
Ubuntu22.04下源码编译安装USD-Brep
c++·ubuntu·nvidia·usd-brep
鱼很腾apoc12 小时前
【MySQL】第4期 用户管理与 C 语言连接编程详解
linux·服务器·c语言·mysql·connector/c
衍玊12 小时前
多路转接原理与应用
c++
himobrinehacken14 小时前
位运算揭秘:左右移与符号位陷阱
c语言·c++·算法·安全
水饺编程16 小时前
第2章:Linux 基础,rm 命令
linux·c语言·汇编
Android小码家16 小时前
Vehicle 实战 自定义属性+测试demo
java·c++·framework·vhal·vehicle
hetao173383716 小时前
2026-10-19 hetao1733837 的刷题记录
c++·算法
夏虫不可与之言冰17 小时前
第三课 点亮 LED 与定时器非阻塞闪烁
c语言·c++·vscode·单片机·嵌入式硬件·物联网
辛苦才能17 小时前
C++ 哈希表深度解析:删除为什么必须打标记,负载因子为什么卡 0.7
开发语言·数据结构·c++·算法