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

题目描述

给定一个 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;
}
相关推荐
旖旎夜光7 分钟前
【C++ 基础入门】C++ 多态(中):虚函数表、多态原理与动静绑定
开发语言·c++·笔记·学习
希和20271 小时前
C语言程序设计题|有序数组插入数字冒泡排序
c语言·数据结构·算法
旖旎夜光1 小时前
【C++ 基础入门】C++多态(下):单/多继承虚表、多态补充与 21 道高频题
开发语言·c++·笔记·学习
apcipot_rain11 小时前
C++转Java日记(03)
java·开发语言·c++
布莱克60511 小时前
C++ 中 map 的 insert 与 emplace:key 已存在时会覆盖吗?
开发语言·数据结构·c++·算法·map
xys_67812 小时前
深挖C++:类和对象(中)
开发语言·c++
D e re k ZH14 小时前
C++ 系统学习手记:从语法细节到工程实践
开发语言·数据结构·c++·算法
xiaoye-duck15 小时前
《C++ 项目:手写大模型接入 SDK》Ollama接口设计(上):初始化、全量响应实现和测试
开发语言·网络·c++·语言模型
zaizai100716 小时前
【Effective Modern C++】学习第一章
c++
Zwawa16 小时前
屏幕不止一种:OLED、LCD1602字符屏、TFT/IPS图形屏和串口屏怎么用,这与TTY和PTY又有什么关系
c语言·单片机·嵌入式