简体   繁体   中英

Finding longest increasing path in a matrix

This is the online judge, https://leetcode.com/problems/longest-increasing-path-in-a-matrix/

why I cannot get the result using DFS?

As you kown from each cell, either move to four directions: left, right, up or down.

Store the length of the longest increasing path.

/*

for each elem, neighbours dfs

*/
class Solution {
public:
    int longestIncreasingPath(vector<vector<int>>& matrix) {
        int row = matrix.size();
        int col = matrix[0].size();
        int x[] = {0,1,0,-1};// l-r       -1,1    
        int y[] = {1,0,-1,0};// up-down   +1,-1
        int maxlen = 0;

        for(int i = 0; i < row; i++){
            for(int j = 0; j< col; j++){
                // each node in the matrix[i][j], neighbours
                int len = 0;
                dfs(maxlen, len, i, j, x, y, matrix);
            }
        }
        return maxlen;
    }

private:
    bool isIn(int x, int y, int row, int col){
        if(x>=0&&x<=col && y>=0&&y<=row) return true;
        else return false;
    }

    void dfs(int& maxlen, int len, int i, int j,int* x, int* y, vector<vector<int>> matrix){
        int row = matrix.size();
        int col = matrix[0].size();

        for(int k = 0; k < 4; k++){
            int i_t = i+x[k];//the current position
            int j_t = j+y[k];
            if(isIn(i_t,j_t,row,col)&& (matrix[i_t][j_t]>matrix[i][j]) ){ // if inside the matrix, within the boundary&& the value of (i_t,j_t)> 
                len+=1;
                maxlen = max(len,maxlen);
                dfs(maxlen, len, i_t, j_t, x, y, matrix);
            }
        }
    }
};

There are multiple problems with this code.

  1. if(x>=0&&x<=col && y>=0&&y<=row) should be changed to if(x>=0&&x<col && y>=0&&y<row)
  2. You are adding all the path that originate from one element together which result in a wrong answer. This part of code

    len+=1; maxlen = max(len,maxlen); dfs(maxlen, len, i_t, j_t, x, y, matrix);

    should be changed to:

     //len+=1; maxlen = max(len+1,maxlen); dfs(maxlen, len+1, i_t, j_t, x, y, matrix);

    so that you don't add all the paths in different directions together.

    1. You are solving a lot of overlapping problems. Once you call dfs(r,c) you can save its result, and use that value for future references (dynamic programming) .

This is how I would have implemented it:

#include <vector>
#include <iostream>
#include <map>
using namespace std;

map< pair<int,int>, int > dp;
pair<int,int> moves[] = {{0,1},{0,-1},{1,0},{-1,0}};
vector<vector<int> > matrix = { {3,4,5},
                                {3,2,6},
                                {2,2,1}};

int dfs(int r, int c, int n_rows, int n_cols){
    pair<int,int> p = make_pair(r,c);
    if ( dp.count(p) ){
        return dp[p];
    }
    int mx = 0;
    for ( int i=0; i<4; ++i ){
        int next_r = r+moves[i].first;
        int next_c = c+moves[i].second;
        if ( 0<=next_r && next_r < n_rows && 0<=next_c && next_c < n_cols ){
            if ( matrix[next_r][next_c] > matrix[r][c] )
                mx = max(mx, dfs(next_r, next_c, n_rows, n_cols));
        }
    }
    mx++;
    dp[p] = mx;
    return mx;
}

int main(){
    int rows = matrix.size();
    int cols = matrix[0].size();
    int result = 0;
    for ( int i=0; i<rows; ++i ){
        for ( int j=0; j<cols; ++j ){
            result = max(result, dfs(i,j,rows,cols));
        }
    }
    cout << result << endl;                                    
}

This was my solution using DFS + Memoization

class Solution {
    int r;
    int c;
public:
    int longestIncreasingPath(vector<vector<int>>& matrix) {
        r = matrix.size();
        if(r == 0) return 0;
        c= matrix[0].size();
        int maxlength = 0;
        vector<vector<int>> dfs(r, vector<int>(c, 0));
        for(int i = 0; i < r; ++i) {
            for(int j = 0 ; j < c; ++j) {
                int curr = recursive(i,j, dfs, matrix);
                maxlength = max(maxlength, curr); 
            }
        }
        return maxlength;
    }

    int recursive(int i, int j, vector<vector<int>>& dfs, vector<vector<int>>& matrix) {
        if(dfs[i][j] != 0) return dfs[i][j];
        else {
            int maxi = 1;

            // b.c 1
            if (i-1 >= 0 && (matrix[i-1][j]>matrix[i][j])) {
                maxi = max(maxi,1+ recursive(i-1, j, dfs, matrix));
            }

            // b.c 2
            if (j -1 >=0 && (matrix[i][j-1]>matrix[i][j])) {
                maxi = max(maxi,1+ recursive(i, j-1, dfs, matrix));
            }

            // b.c 3

            if (i+1 < r && (matrix[i+1][j]>matrix[i][j])) {
                maxi = max(maxi,1+ recursive(i+1, j, dfs, matrix));
            }

            // b.c. 4
            if(j+1 < c && (matrix[i][j+1]>matrix[i][j])) {
                    maxi = max(maxi,1+ recursive(i, j+1, dfs, matrix));
            }            
         dfs[i][j] = maxi;
        return maxi;
        }

    }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM