Max Area of Island
The LeetCode-official cousin of `largestComponent`: same size-counting `exploreGraph` as `minimumIsland`, but reduced with `Math.max` instead of `Math.min` — the third combination this series has run through today, after `islandCount` just counted islands and `minimumIsland` found the smallest one.
The problem
Implement `maxAreaOfIsland(grid)` over a grid of `'1'`s (land) and `'0'`s (water), returning the area of the largest island. Adjacency is the same as every grid problem in this series: up/down/left/right, not diagonal.
Unlike `minimumIsland`, an empty or all-water grid has a perfectly ordinary answer here — `0`. An island's area can't be negative, so `0` doubles as both 'no island found' and the correct identity value for `Math.max`, with no sentinel like `Infinity` required.
The approach
`getIslandArea` keeps the same three rejections as every `exploreGraph` in this series — out of bounds, water, already visited — but returns `0` instead of `Infinity`, mirroring `largestComponent`'s guard rather than `minimumIsland`'s.
The outer loop reduces with `Math.max(maxArea, getIslandArea(...))`, so a revisited or water cell's `0` can never beat a real island's area — the same `0`/`Math.max` pairing `largestComponent` used over an adjacency list, just with grid neighbours computed from coordinates instead of looked up.
The BFS body is identical in shape to `islandCount` and `minimumIsland`: a queue of `[r, c]` pairs, four hardcoded directions, a string-keyed `visited` set, and a size counter incremented once per newly queued land cell. The only line unique to this version is the water check itself — `grid[r][c] == '0'` rather than `=== 'W'`, since LeetCode encodes the grid as `'1'`/`'0'` characters instead of the course's `'L'`/`'W'`.
The solution
/**
* @param {number[][]} grid
* @return {number}
*/
var maxAreaOfIsland = function (grid) {
const visited = new Set()
let maxArea = 0
for (let r = 0; r < grid.length; r++) {
for (let c = 0; c < grid[0].length; c++) {
maxArea = Math.max(maxArea, getIslandArea(grid, r, c, visited))
}
}
return maxArea
};
function getIslandArea(grid, r, c, visited) {
const colInbound = r >= 0 && r < grid.length;
const rowInbound = c >= 0 && c < grid[0].length;
const pos = `${r},${c}`
if (!rowInbound || !colInbound || grid[r][c] == '0' || visited.has(pos)) {
return 0
}
const q = [[r, c]]
visited.add(pos);
const directions = [[1, 0], [-1, 0], [0, 1], [0, -1]]
let islandLen = 1
while (q.length) {
const [cr, cc] = q.shift()
for (let [dr, dc] of directions) {
const [nr, nc] = [cr + dr, cc + dc]
const nColInbound = nc >= 0 && nc < grid[0].length;
const nRowInbound = nr >= 0 && nr < grid.length;
const inBound = nColInbound && nRowInbound
const neighborPos = `${nr},${nc}`;
if (inBound && grid[nr][nc] == '1' && !visited.has(neighborPos)) {
visited.add(neighborPos);
q.push([nr, nc]);
islandLen++
}
}
}
return islandLen
}Time O(R * C)Space O(R * C)