Search code examples
calgorithmmatrix2dlongest-path

Find longest sequence of decreasing numbers given a 2D matrix


Given a 2D array, find the longest sequence of decreasing numbers. Constraints are: 1. you cannot compare elements diagonally.

For Eg:

56 14 51 58 88
26 94 24 39 41
24 16 8 51 51
76 72 77 43 10
38 50 59 84 81
5 23 37 71 77
96 10 93 53 82
94 15 96 69 9
74 0 62 38 96
37 54 55 82 38

Here the ans is: 7

And for below matrix

1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

Answer is 25 since I can move in fashion 25 -> 24 -> 23 -> 22 -> ....and so on..till i reach 1.

Could somebody help me with the algorithm.

This was my initial code :

int dx[4] = {0, 1, -1, 0};
int dy[4] = {1, 0, 0, -1};

int findSequence(int x, int y)
{
    for(int i = 0; i < 4; ++i)
    {
        int new_x = x + dx[i];
        int new_y = y + dy[i];
        if(isValid(new_x, new_y) && data[x][y] > data[new_x][new_y])
        {
            std::cout << "" << data[x][y] << " -> " << data[new_x][new_y] << " ";
            int tmp =  1 + findSequence(new_x, new_y, isVisited);
            //std::cout << " "<< tmp << " ";
            return tmp;
        }
    }
}

Thanks


Solution

  • You can use recursion. Suppose we want to get maximum sequence starting from indices (i,j). Then we can move in any of the 4th direction (i1,j1) if A[i][j] > A[i1][j1] where A is the 2D array.

    const int N=50;
    int A[N][N];
    int res=0; // maximum result
    
    int calc(int i, int j) {
        int r=1;   // only this element forms a single element sequence
        if(A[i][j]>A[i][j+1]) r=max(r, 1+ calc(i, j+1));
        if(A[i][j]>A[i][j-1]) r=max(r, 1+ calc(i, j-1));
        if(A[i][j]>A[i+1][j]) r=max(r, 1+ calc(i+1, j));
        if(A[i][j]>A[i-1][j]) r=max(r, 1+ calc(i-1, j));
        res=max(res,r);
        return r;
    }
    

    Complexity: O(mn) if result is memoized in a 2D array where m is number of rows and n number of columns.