Quick Overview

Given a grid of land and water, convert at most one water cell to land and return the size of the largest island that can result. An onsite follow-up coding problem that tests connected-component sizing, joining neighboring islands without counting one twice, and efficiency on grids up to 500 by 500.

Largest Island After Converting at Most One Water Cell to Land

Company: Oracle

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Onsite

You are given a rectangular grid in which `1` marks land and `0` marks water, and land cells connected horizontally or vertically form islands. You may change at most one water cell into land. Return the number of cells in the largest island the grid can contain after that change. In the interview, this followed the island-counting question. ### Function Signature ```python def largest_island_after_one_change(grid: list[list[int]]) -> int: ``` ### Rules - Two land cells are in the same island when a path of land cells joins them, each step moving one cell up, down, left or right; cells that touch only at a corner are not connected. - You may change one `0` to `1`, or change nothing. The answer is the largest island size over all of these choices. - The size of an island is its number of cells. If the grid has no water, the answer is the number of cells in the grid. - Coordinates in the examples are written `(row, column)`, counted from 0. ### Constraints - `1 <= len(grid) <= 500` and `1 <= len(grid[i]) <= 500`, with all rows the same length - every `grid[i][j]` is `0` or `1` - the answer is at most `250000` ### Examples **Example 1** ```text Input: grid = [[1, 0], [0, 1]] Output: 3 ``` Changing either water cell joins the two single-cell islands: 1 + 1 + 1 = 3. **Example 2** ```text Input: grid = [[1, 1], [1, 1]] Output: 4 ``` There is no water to change; the whole grid is already one island. **Example 3** ```text Input: grid = [[1, 1, 0, 0], [0, 0, 0, 1], [1, 0, 1, 1]] Output: 5 ``` Changing (2, 1) joins the single cell at (2, 0) and the three-cell island {(1, 3), (2, 2), (2, 3)}: 1 + 1 + 3 = 5. Changing (1, 2) touches that three-cell island on two sides but adds it only once, for a size of 4.

Overview: Given a grid of land and water, convert at most one water cell to land and return the size of the largest island that can result. An onsite follow-up coding problem that tests connected-component sizing, joining neighboring islands without counting one twice, and efficiency on grids up to 500 by 500.

Read the full Oracle Software Engineer interview experience this question came from

You are given a rectangular grid in which `1` marks land and `0` marks water. Land cells connected horizontally or vertically form islands. You may change at most one water cell into land. Return the number of cells in the largest island the grid can contain after that change. Implement `largest_island_after_one_change(grid)`, where `grid` is a list of equal-length rows of integers, and return the answer as an integer. ### Rules - Two land cells are in the same island when a path of land cells joins them, each step moving one cell up, down, left or right; cells that touch only at a corner are not connected. - You may change one `0` to `1`, or change nothing. The answer is the largest island size over all of these choices. - The size of an island is its number of cells. If the grid has no water, the answer is the number of cells in the grid. - Coordinates in the examples are written `(row, column)`, counted from 0. ### Constraints - `1 <= len(grid) <= 500` and `1 <= len(grid[i]) <= 500`, with all rows the same length - every `grid[i][j]` is `0` or `1` - the answer is at most `250000`, so it never exceeds 2^31 - 1 and a 32-bit `int` is enough in Java and C++ ### Examples **Example 1** ```text Input: grid = [[1, 0], [0, 1]] Output: 3 ``` Changing either water cell joins the two single-cell islands: 1 + 1 + 1 = 3. **Example 2** ```text Input: grid = [[1, 1, 0, 0], [0, 0, 0, 1], [1, 0, 1, 1]] Output: 5 ``` Changing (2, 1) joins the single cell at (2, 0) and the three-cell island {(1, 3), (2, 2), (2, 3)}: 1 + 1 + 3 = 5. Changing (1, 2) touches that three-cell island on two sides but adds it only once, for a size of 4.

Constraints

  • 1 <= len(grid) <= 500 and 1 <= len(grid[i]) <= 500, with all rows the same length
  • every grid[i][j] is 0 or 1
  • the answer is at most 250000 (it never exceeds 2^31 - 1, so a 32-bit int is enough in Java and C++)

Examples

Input: ([[0]],)

Expected Output: 1

Explanation: Minimum valid grid, a single water cell: changing it gives a one-cell island.

Input: ([[1]],)

Expected Output: 1

Explanation: Minimum valid grid with no water: the answer is the cell count, 1, with nothing changed.

Hints

  1. Changing one water cell can only connect it to islands that share an edge with that cell. What would you want to know about each of those islands up front?
  2. One island can touch a water cell on more than one side; make sure its cells are counted only once.
  3. Remember the grid may have no water at all, and a single island can wind through most of a 500 x 500 grid.

Loading coding console...

Show the approach

Approach

Label every island once with an iterative flood fill that uses an explicit stack, so a long winding island cannot overflow the call stack. Each land cell gets the id of its island, and each id records how many cells it has. The running best starts as the largest existing island, which covers the change-nothing choice and the grid with no water at all. Then, for every water cell, collect the island ids of its up, down, left and right neighbours that lie inside the grid, skip water (id 0) and duplicates, and score 1 plus the sizes of the distinct islands. Correctness: islands are the maximal 4-connected groups of land, and converting one cell changes nothing else, so the new island containing that cell is exactly the cell itself plus every island sharing an edge with it, and every other island is unchanged and already counted in the starting best. Counting each distinct id once is what stops an island that wraps around the cell, touching it on two or more sides, from being counted twice. Diagonal neighbours are never looked at, matching the rule that corner contact does not connect cells. Edge and corner cells simply have fewer in-bounds neighbours; indices are bounds-checked rather than wrapped. Every cell is pushed onto the stack at most once while labelling and makes at most four neighbour lookups while scoring.

Time complexity:
O(R * C)
Space complexity:
O(R * C)