Explanation + dfs
\n/**\n * @param {number[][]} matrix\n * @return {number[][]}\n */\n\n/*\n\nbasic idea -->\npopulate cells reached from atlantic and cells reached from pacific 
```\n/**\n * @param {number[][]} matrix\n * @return {number[][]}\n */\n\n/*\n\nbasic idea -->\npopulate cells reached from atlantic and cells reached from pacific with dfs\nloop through matrix\nadd coords to return array if they exist in both the atlantic matrix and the pacific matrix\nreturn result\n\ndfs --> \n1. base - return if out of bounds\n2. base - return if our previous spot was larger because we are only marking spot as true\nif it is larger than prev (prev) **this is tricky, we aren\'t checking if the water is\nable to flow to this spot from a previous spot...instead we are checking if water can flow out FROM this spot\nTO the "prev" spot, so really prev is kind of a confusing name, because it represents the next spot that water could flow to\n2. base - if the spot is already marked as true we can just return, because it means that water from this spot can already reach ocean\n3. if we\'ve reached this point it means that our flow has not yet been interrupted from our starting point\nso we CAN reach our ocean (pacific or atlantic) from the current spot, so we simply mark that in our ocean i.e. ocean[i][j] = true\n4. call dfs recursively on all 4 surrounding spots\n\n\n*/\nvar pacificAtlantic = function(matrix) {\n    if (matrix.length === 0) return [] \n   let numRows = matrix.length\n   let numCols = matrix[0].length\n   \n   let atlantic = []\n   let pacific = []\n   for (let i = 0;i<numRows;i++){\n       atlantic.push(new Array(numCols).fill(false))\n       pacific.push(new Array(numCols).fill(false))\n   }\n   \n   for (let col=0 ;col<matrix[0].length;col++){\n       dfs(matrix, 0, col, Number.MIN_SAFE_INTEGER, pacific)\n       dfs(matrix, numRows - 1, col, Number.MIN_SAFE_INTEGER, atlantic)\n   }\n    \n    for (let row = 0;row<matrix.length; row++){\n        dfs(matrix, row, 0, Number.MIN_SAFE_INTEGER, pacific)\n        dfs(matrix, row, numCols - 1, Number.MIN_SAFE_INTEGER, atlantic)\n    }\n    \n    let res = []\n    for (let i=0;i<numRows;i++){\n        for (let j=0;j<numCols;j++){\n            if (atlantic[i][j] && pacific[i][j]){\n                res.push([i, j])\n            }\n        }\n    }\n    return res\n}\n   \n\n\nconst dfs = (matrix, i, j, prev, ocean) =>{\n  //checkOutOfBounds\n    if (i<0 ||\n       i > matrix.length -1 ||\n       j < 0 ||\n       j > matrix[i].length - 1\n      ) return\n    \n    \n    if (matrix[i][j] < prev) return\n    if (ocean[i][j]) return\n    ocean[i][j] = true\n    \n    dfs(matrix, i+1, j, matrix[i][j], ocean)\n    dfs(matrix, i-1, j, matrix[i][j], ocean)\n    dfs(matrix, i, j+1, matrix[i][j], ocean)\n    dfs(matrix, i, j-1, matrix[i][j], ocean)    \n}\n\n\n```
['Depth-First Search', 'JavaScript']