2

I was working on this Leetcode problem Longest Line of Consecutive One in Matrix subscription required, but I cannot figure out why I get an error with regards to indexing. That is, Line 15: TypeError: Cannot set property '0' of undefined.

What's up with this bug?

/**
 * @param {number[][]} M
 * @return {number}
 */
var longestLine = function(M) {
  if(!M.length) return 0;

  let ones = 0;
  let dp = [[[]]];
  for(let i=0; i<M.length; i++){
    for(let j=0; j<M[0].length; j++){
      if(M[i][j] === 1){
        //dp[i][j] = undefined ? [] : dp[i][j];
        console.log(dp);
        dp[i][j][0] = i>0 ? dp[i-1][j][0] + 1 : 1;  // ----> line 15                        //left
        dp[i][j][1] = j>0 ? dp[i][j-1][1] + 1 : 1;                          //right
        dp[i][j][2] = (i > 0 && j > 0) ? dp[i-1][j-1][2]+1 : 1;             //upper left 
        dp[i][j][3] = (i > 0 && j < M.length - 1) ? dp[i-1][j+1][3] + 1 : 1; //lower left
        ones = Math.max(ones, dp[i][j][0], dp[i][j][1], dp[i][j][2], dp[i][j][3]); 
      }
    }
  }
  return ones;
};
Abion47
  • 22,211
  • 4
  • 65
  • 88
guest
  • 2,185
  • 3
  • 23
  • 46
  • shouldn't `M[0].length` be `M[i].length` – epascarello Feb 08 '19 at 19:19
  • 3
    You've declared `dp` to be a 3D array where each dimension has a length of 1. Whenever `i` or `j` are anything other than 0, `dp[i][j]` is going to be referring to an element in one or both of the first two dimensions that doesn't exist. Therefore, `dp[i][j]` is going to be undefined, so `dp[i][j][0]` is going to throw an error. – Abion47 Feb 08 '19 at 19:19
  • So how do you declare a full 3D array? – guest Feb 08 '19 at 19:34
  • Just initialize `dp[i][j] = []`. – Heretic Monkey Feb 08 '19 at 19:44
  • Possible duplicate of [How to create a multi dimensional array in Javascript?](https://stackoverflow.com/questions/8427599/how-to-create-a-multi-dimensional-array-in-javascript) – Heretic Monkey Feb 08 '19 at 19:47
  • if you're willing to bend your mind a little, an indexer for a linear array might help. `dp = new Array(dimx*dimy*dimz); at = (x,y,z) => (x*dimy+y)*dimz+z;` Then you just access with the syntax `dp[at(x,y,z)]` – Wyck Feb 08 '19 at 19:55
  • You should only initialize the full 3D array if you already know exactly what size every dimension is going to be. Otherwise, you should instead dynamically create every dimension the first time it is visited. – Abion47 Feb 08 '19 at 20:30
  • yes i know what size the arrays are. M.length x M[0].length x 4 – guest Feb 08 '19 at 20:33
  • @HereticMonkey i tried that in my uncommented lines but didn't work. – guest Feb 08 '19 at 20:34
  • In your commented line you set `dp[i][j] = dp[i][j]` since undefined is falsy. You can just do `dp[i][j] = dp[i][j] || [];` You may need to initialize `dp[i] = dp[i] || [];` also, much like [this answer on the duplicate shows](https://stackoverflow.com/a/8427615/215552). – Heretic Monkey Feb 08 '19 at 20:36

0 Answers0