-1

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

0726
  • 315
  • 2
  • 13

3 Answers3

1

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.

xashru
  • 3,400
  • 2
  • 17
  • 30
  • Starting at 25 in the `2nd matrix`, it should have given `25` as the res but I am getting `10`. – 0726 May 03 '20 at 12:43
0

I would suggest you visit the numbers in decreasing order.

Initialize a matrix to all zeros. This matrix will represent the longest sequence that ends in this spot.

Now go through all the positions in the matrix (in order of decreasing value in the original matrix). For each position set the value in the matrix to 1 + the largest value in any neighbouring location.

After you have visited all positions, the largest value in the matrix will be the solution to your problem.

Peter de Rivaz
  • 33,126
  • 4
  • 46
  • 75
  • Approach seems ok, but needs two corrections: (a) final result requires +1 (or intialize countingmatrix to 1, not 0); (b) when scanning neighbouring values, only consider cells where the basevalue (original matrix) is larger, otherwise you'll get wrong results when neighbouring cells in the input-matrix have identical values. – Bert te Velde Aug 06 '15 at 15:34
  • Not sure if I can ask this... but can moderators please increase rating of this question? I have added the code as expected by community. And improved the overall content. – 0726 May 08 '20 at 16:14
0

Here is the code with memoization.

class Solution {


int[] xdir = new int[]{-1,1,0,0};
int[] ydir = new int[]{0,0,-1,1};

public boolean isValid(int i, int j, int m, int n){
    if(i < 0 || j < 0 || i >= m || j >=n)return false;
    return true;
}

public int dfs(int i, int j, int[][] mat, int[][]memo, int m, int n){
    if(memo[i][j] != 0)return memo[i][j];
    
    
    int mx = 1;
    for(int k = 0; k < 4; k++){
        int ni = i + xdir[k];
        int nj = j + ydir[k];
        if(isValid(ni, nj, m, n) && mat[ni][nj] < mat[i][j]){
           mx = Math.max(mx, 1 +  dfs(ni, nj, mat, memo, m, n));
        }    
    }
    memo[i][j] = mx;
    return mx;
    
}
public int longestDecreasingPath(int[][] mat) {
    
    int m = mat.length;
    int n = mat[0].length;
    
    
    int[][] memo = new int[m][n];
    
    
     int ans  = 0;
    for(int i = 0; i < m; i++){
        for(int j = 0; j < n; j++){
            if(memo[i][j] == 0){
              ans = Math.max(ans,   dfs(i, j, mat, memo, m, n));
            }
            
        }
    }
   
    
    return ans;
}

}