[Question] 329. The longest incremental path in the matrix-Given an mxn integer matrix matrix, find out the length of the longest incremental path. For each cell, you can move up, down, left, and right.

Subject: 329. The longest incremental path in the matrix

Given an mxn integer matrix matrix, find the length of the longest incremental path.

For each cell, you can move up, down, left, and right. You cannot move in the diagonal direction or move outside the boundary (that is, no orbiting is allowed).

Insert picture description here
Insert picture description here

answer:

Think of the matrix as a directed graph, and each cell corresponds to a node in the graph. If the values ​​of two adjacent cells are not equal, there is a smaller value between the two adjacent cells A directed edge that points to a larger value. The problem is transformed into finding the longest path in a directed graph.

Depth-first search is a very intuitive method. Perform a depth-first search starting from a cell to find the longest increasing path from that cell. After the depth-first search is performed on each cell separately, the length of the longest incremental path in the matrix can be obtained.

But if you use the naive depth-first search, the time complexity is exponential and will exceed the time limit, so it must be optimized.

The reason for the high time complexity of the naive depth-first search is that a large number of repeated calculations are performed. The same cell will be visited multiple times, and the calculation must be recalculated every time it is visited. Since the length of the longest incremental path corresponding to the same cell is fixed, it can be optimized using memorization. The matrix memo is used as the cache matrix, and the results of the cells that have been calculated are stored in the cache matrix.

Using memoized depth-first search, when a cell (i,j)(i,j) is accessed, if memo[i][j]!=0, it means that the result of the cell has been calculated, then directly from Read the result in the cache. If memo[i][j]==0, it means that the result of the cell has not been calculated, then search and store the calculated result in the cache.

After traversing all the cells in the matrix, the length of the longest incremental path in the matrix can be obtained.

// 矩阵数据的上、下、左、右四个移动
// 矩阵数据要一组一组的看
const int dirs[4][2] = {
    
    {
    
    -1, 0}, {
    
    1, 0}, {
    
    0, -1}, {
    
    0, 1}};
// 全局变量
int rows, columns;

// 找出 最长递增路径 的长度
int longestIncreasingPath(int** matrix, int matrixSize, int* matrixColSize)
{
    
    
	// 矩阵为空
    if (matrixSize == 0 || matrixColSize[0] == 0)
        return 0;
    rows = matrixSize;
    columns = matrixColSize[0];
    int** memo = (int**)malloc(sizeof(int*) * rows);
    for (int i = 0; i < rows; i++)
    {
    
    
        memo[i] = (int*)malloc(sizeof(int) * columns);
        memset(memo[i], 0, sizeof(int) * columns);
    }
    int ans = 0;
    for (int i = 0; i < rows; i++)
    {
    
    
        for (int j = 0; j < columns; j++)
        {
    
    
            ans = fmax(ans, dfs(matrix, i, j, memo));
        }
    }
    free(memo);
    return ans;
}

// 深度优先搜索
int dfs(int** matrix, int row, int column, int** memo)
{
    
    
    if (memo[row][column] != 0)
        return memo[row][column];
    // 长度+1
    memo[row][column]++;
    for (int i = 0; i < 4; i++)
    {
    
    
        // const int dirs[4][2] = {
    
    {-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        int newRow = row + dirs[i][0], newColumn = column + dirs[i][1];
        if (newRow >= 0 && newRow < rows && newColumn >= 0 && newColumn < columns && matrix[newRow][newColumn] > matrix[row][column])
            memo[row][column] = fmax(memo[row][column], dfs(matrix, newRow, newColumn, memo) + 1);
    }
    return memo[row][column];
}

Guess you like

Origin blog.csdn.net/m0_46613023/article/details/114045160