Boundary-safe neighbor testing.
Reach into neighboring cells without crashing on the grid's edges — the defensive pattern that powers every grid-game problem.
Looking at a cell's neighbors is essential in grid problems. But cells on the edges have fewer neighbors than cells in the interior. Accessing grid[-1][c] or grid[grid.length][c] throws an ArrayIndexOutOfBoundsException.
Boundary-safe neighbor testing wraps every access in a bounds check. The common idiom is a helper method isInBounds(r, c) that returns true only for valid coordinates — combined with short-circuit evaluation, your code stays both safe and clean.
Check coordinates before reading cells.
Short-circuit && is your shield.
The helper method
private static boolean isInBounds(int[][] grid, int r, int c) {
return r >= 0 && r < grid.length
&& c >= 0 && c < grid[0].length;
}
Returns true only when both r and c point to an actual cell.
Safe neighbor access
if (isInBounds(grid, r - 1, c) && grid[r - 1][c] == 1) {
// safely use the neighbor above
}
Short-circuit && means the second condition is only checked when the first is true. The bounds check protects the access.
Counting in-bounds neighbors
int[] dr = {-1, 1, 0, 0};
int[] dc = {0, 0, -1, 1};
public static int neighborSum(int[][] grid, int r, int c) {
int sum = 0;
for (int d = 0; d < 4; d++) {
int nr = r + dr[d];
int nc = c + dc[d];
if (isInBounds(grid, nr, nc)) {
sum += grid[nr][nc];
}
}
return sum;
}
The dr/dc "delta" arrays describe the four orthogonal directions (up, down, left, right). The bounds check ensures every access is valid.
Order matters
Bounds check first, then the value check. Reversing the order — checking the value before bounds — will crash at the edges.
Vocabulary for defensive coding.
These terms anchor AP grid problems.
- Boundary check — verifying coordinates are inside the grid.
- Neighbor — an adjacent cell (orthogonal or diagonal).
- Defensive programming — coding so invalid inputs don't crash the program.
- Short-circuit evaluation — Java skips the right side of
&&when the left is false. - Delta array — a fixed array of offsets used to compute neighbor positions.
- ArrayIndexOutOfBoundsException — the runtime error you're preventing.
How bounds checking is tested.
Order, short-circuiting, and corner cells are the classic exam traps.
- Bounds before value. If the check order is reversed, the access fails on edge cells.
- Corner cells. Have only two in-bounds neighbors; your code must still produce the correct count.
- 1x1, 1xN, Nx1 grids. Verify your method doesn't crash on these.
FRQ tip: writing a private static boolean isInBounds(...) helper is graded as good design, not extra work.
Sum the four orthogonal neighbors of a corner.
Test edge behavior on the trickiest cell.
Problem. Sum the orthogonal neighbors of cell (0, 0) in this grid:
{{1, 2, 3},
{4, 5, 6},
{7, 8, 9}}
Trace the four directions:
- Up:
(-1, 0)→ out of bounds, skip. - Down:
(1, 0)→ in bounds, value 4. Sum = 4. - Left:
(0, -1)→ out of bounds, skip. - Right:
(0, 1)→ in bounds, value 2. Sum = 6.
Answer. 6.
Why this matters. Without the bounds check, the up and left accesses would throw exceptions immediately. With the check, the corner naturally has only two contributing neighbors.
Bounds-check failures.
All of these crash on a single edge cell.
- Wrong order.
grid[r-1][c] == 1 && isInBounds(...)crashes; the access happens before the check. - Forgetting one boundary. Checking
r >= 0but notr < grid.lengthprotects only one side. - Off-by-one. Using
r <= grid.lengthinstead of<. - Using
grid[r].lengthwhenrmight be out of bounds — read columns fromgrid[0].lengthin the helper.
Bounds-check checklist.
Four conditions that must all hold.
Boundary Reference
AP Quick Reference| Check | Purpose | AP Exam Tip |
|---|---|---|
r >= 0 |
Above the grid | Negative indices fail. |
r < grid.length |
Below the grid | Use <, not <=. |
c >= 0 |
Left of the grid | Same form as row check. |
c < grid[0].length |
Right of the grid | Safe for rectangular grids. |
Combined with && |
All four must hold | Short-circuits left to right. |
How to bake in defensive habits.
Write the helper once; use it everywhere.
Use the three practice tools below this lesson in order:
- MCQ Practice — for each access on an edge or corner, decide which directions are valid before answering.
- Java Lab — write neighborSum, neighborMax, and neighborCount using
isInBounds. Test on corners and 1x1 grids. - FRQ Practice — make
isInBoundsa helper method in every grid FRQ. Mention "defensive bounds check" in comments.
Practice — attempt these now.
AP-style assessments aligned to this lesson. Time them.