algorithms
javascript
leetcode
codenewbie
Published: Wed Jun 09 2021 (~ 6 min)
Read on Dev.toFor this entry in my algorithm walkthrough series, we will be looking at a 2D matrix search using a depth-first search approach.
We will first discuss the the problem, the solution, and then use a visualizer I created (and teased about in my last blog) to better understand the search process.
The specific problem we will be walking through, is problem Leetcode #695: Max Area of Island. The direct problem description found on Leetcode is:
You are given an m x n binary matrix grid. An island is a group of 1's (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water.
The area of an island is the number of cells with a value 1 in the island.
Return the maximum area of an island in grid. If there is no island, return 0.
For example, the grid of:
[object Object]
Would return a value of 6, not 11, since the largest area of consecutive tiles in orthogonal directions is only 6, with the additional 5 tiles being connected diagonally, and thus considered a separate island. Leetcode provided this model to demonstrate the example:
If we were to perform this task mentally, the general approach would be to pick a starting point on an island, and then count each land tile that is connected to the current one, without repeating. If the island had different peninsulas or branches, we could count all of the land tiles in one peninsula before counting the rest of the tiles in the other.
This mental model is the exact process we can replicate with a depth first solution, previewed below:
In implementing this approach, we will need to:
maxArea
variable to be whichever is greater: the result of the most recent island, or the previous value of maxArea.The second consideration that must be made, is how to keep track the land tiles that have already been visited:
visited
array, or object and add the coordinate pair for each land tile as it is counted. You would then need to check within this visited
object to see if it already includes those coordinates. The advantages to this approach, are that it doesn't mutate the original grid, however more memory is going to be required for the function since we will be creating a new object.visited
object, but the original grid will be mutated.For my solution, I chose to mutate the grid, in particular because assigning different values based on a tiles "status" would allow me to model them different in a visualizer.
Using the pseudo-code in the previous section, we can implement the mapAreaOfIsland
function in Javascript as shown below:
[object Object]
For myself, it often helps to have a visual model of a process that illustrates the steps that are occurring. To further my own understanding, and to hopefully help you, I created a visualizer using CodeSandbox To help model the depth first search.
In this visualizer, the solution implementation above was modified so that the current state of the tile: unvisited land, unvisited water, visited land, visited water, andpending (in the stack) was denoted by different numerical values. As the state of the tile changed throughout the function, the value was updated leading to a visual change in the styling. Here is a preview of the search for the initial example grid:
Other modifications to the solution that were needed to produce the visualizer included cloning the grid after each mutation in order to update the component state and re-render the component. The sleep()
function described in my last blog allows us also to purposely slow down the solution in order to perceive and follow the search pattern. If you would like to change the speed of the visualizer, you can adjust the {sleep: }
option argument on line 31 where the custom hook is invoked.
Aside from the three pre-defined grids, I also added acreate a custom map feature to create different scenarios to run the search on. Enter the number of rows/columns you'd like, and then click a tile to toggle it as land or water. After selecting "Use this map" you can search against this one shown below: