Understand
30-second explanation
Build the interview-ready mental model before comparing implementations.
You're given a fixed 6×6 grid and must return the maximum hourglass sum. An hourglass is the 7 cells in a 3×3 block minus the two middle-side cells. There are exactly 16 hourglass positions (top-left corner ranges over rows 0–3 and columns 0–3). Sum each one with a closed-form expression and track the max — no nested scanning of each block needed.
Interview contextWhat is testedWhere candidates slipHow to stand outExplore interview contextHide interview context
What's being tested
Whether you can translate a visual shape into exact index offsets, get the loop bounds right so you never read out of bounds, and remember that an all-negative grid means `best` can't start at 0.
Where candidates slip
Initializing the running max to 0, which returns 0 on a grid where every hourglass sum is negative. Or looping the corner over 0..5 and indexing g[r+2] out of bounds.
How to stand out
Say up front 'the corner ranges over a 4×4 region, so there are exactly 16 hourglasses, and the work is constant'. Name the excluded cells explicitly so the interviewer knows you read the shape, not a full 3×3.
Choose
Compare the available approaches
Use constraints and trade-offs to select the route you can defend in an interview.
Interactive decision treeInteractiveChoose the right approachExplore the full treeCollapse the tree
How to read it:The corner (r, c) ranges over rows 0–3 and columns 0–3, giving 16 positions. The middle-side cells are never read.
Learn & trace
Build each solution step by step
Move from the core idea to a visual trace, implementation, proof, and edge cases.
Approach 1 of 2
Brute Force — Re-check Every Cell of Every 3×3 Block
1Hint 1Explore hintHide hint
How many top-left corners give a valid 3×3 block inside a 6×6 grid? Count the rows and columns the corner can sit on.
2Hint 2Explore hintHide hint
For each block, you only need 7 of its 9 cells. Which two do you skip?
3Hint 3Explore hintHide hint
Add up the 7 cells, compare against the best so far, and remember to start the best at a negative value.
A · Core idea
Walk the top-left corner over every position where a full 3×3 block fits, then sum the 7 hourglass cells of that block directly.
Why the corner stops at row 3 and column 3. A 3×3 block anchored at (r, c) reads cells up to (r+2, c+2). For those to stay inside a 6×6 grid you need r+2 ≤ 5 and c+2 ≤ 5, i.e. r ≤ 3 and c ≤ 3. So the corner ranges over a 4×4 region: 4 rows × 4 columns = 16 hourglasses. Run the corner to row 5 and you index arr[7], which is out of bounds.
Why we only touch 7 cells. The hourglass excludes arr[r+1][c] and arr[r+1][c+2] — the left and right of the middle row. Only the center arr[r+1][c+1] survives. Reading all 9 and subtracting the two would also work, but it's clearer to sum exactly the 7 you want.
Why `best` starts negative. With values down to −9, an hourglass can sum as low as −63, and an entire grid can be negative. If you initialize best = 0, a fully-negative grid returns 0 — a sum that never actually occurs. Start at something like Integer.MIN_VALUE (Java) or float('-inf') (Python).
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
the first example gridInteractive diagram
Why the corner range is 4×4
corner (0,0)r+2 ≤ 5 forces r ≤ 3; the same logic bounds c. Hence 16 positions.
19C · Code with teaching comments
Reference implementation previewpublic int hourglassSum(int[][] arr) { int best = Integer.MIN_VALUE; for (int r = 0; r <= 3; r++) { for (int c = 0; c <= 3; c++) { int top = arr[r][c] + arr[r][c + 1] + arr[r][c + 2];Explore the full codeHide the full code
D · Why it works and complexityO(1) timeO(1) spaceOpen the invariant and proofExplore the proofHide the proof
On a fixed 6×6 grid this 'brute force' is already optimal — the work is a constant 16 hourglasses. The lesson isn't the algorithm; it's getting the loop bounds and the negative initialization right.
ComplexityO(1) time, O(1) space — The grid is fixed at 6×6, so there are a constant 16 hourglasses and each costs a constant 6 additions. Everything here is O(1) — the 'brute' label only means 'no precomputation'.
E · Edge cases and pitfalls5all-negative 6×6 grid — Returns the least-negative hourglass sum (e.g. −6), never 0.Explore edge casesHide edge cases
Edge cases handled
all-negative 6×6 gridReturns the least-negative hourglass sum (e.g. −6), never 0.grid where the best hourglass is at a corner like (0,0) or (3,3)Bounds 0..3 include every corner, so edge hourglasses are still considered.
Pitfalls
- Initializing best to 0 — wrong on all-negative grids.
- Looping the corner to 5 instead of 3 — reads arr[6] or arr[r][6] out of bounds.
- Summing all 9 cells of the 3×3 block instead of the 7 hourglass cells.
Approach 2 of 2 · Optimal
Constant Pass — Closed-Form Over 16 Hourglasses (Optimal)
1Hint 1Explore hintHide hint
Since the grid size is fixed, the number of hourglasses is fixed too. What's that number?
2Hint 2Explore hintHide hint
Each hourglass sum is the same expression with shifted indices — write it once, parameterized by the corner (r, c).
3Hint 3Explore hintHide hint
You never need to revisit a cell or store partial sums; one direct sum per corner is already constant total work.
A · Core idea
For a fixed-size grid the optimal solution is the direct enumeration — there's nothing asymptotically to improve. The value of treating it as 'optimal' is recognizing the structure so you write tight, correct code.
The mask as a closed form. Every hourglass sum is top + mid + bottom where top = arr[r][c] + arr[r][c+1] + arr[r][c+2], mid = arr[r+1][c+1], and bottom = arr[r+2][c] + arr[r+2][c+1] + arr[r+2][c+2]. Writing it as three named pieces makes the shape obvious and the off-by-one mistakes visible.
Why no prefix sum helps. A 2D prefix-sum array shines when you query many overlapping rectangles of varying size. Here the shape is fixed and tiny (7 cells), and there are only 16 queries, so building a prefix table costs more than it saves. Recognizing when not to add machinery is part of the answer.
Generalizing to n×n. If the grid were n×n, the corner would range over rows 0..n−3 and columns 0..n−3, giving (n−2)² hourglasses and O(n²) total work. The 6×6 case is just (6−2)² = 16. Mentioning this generalization signals you understand the bounds rather than memorizing 16.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
the first example gridArray state
top band
2 + 4 + 4 = 10
19C · Code with teaching comments
D · Why it works and complexityO(1) timeO(1) spaceOpen the invariant and proofExplore the proofHide the proof
The trade here is conceptual, not computational: name the three bands of the mask (top, center, bottom) so the index offsets are self-documenting. That single habit kills the off-by-one bugs that sink most attempts at this problem.
ComplexityO(1) time, O(1) space — 16 hourglasses × 6 additions = 96 additions regardless of input. Constant time, constant space.
E · Edge cases and pitfalls5n×n grid with n > 6 — The length-based bounds (rows−2, cols−2) handle any n ≥ 3 with no code change.Explore edge casesHide edge cases
Edge cases handled
n×n grid with n > 6The length-based bounds (rows−2, cols−2) handle any n ≥ 3 with no code change.n = 3 gridExactly one hourglass; the loops run once and return its sum.
Pitfalls
- Hardcoding 4 as the loop bound, then breaking when asked to generalize to n×n.
- Forgetting the negative initialization — the most common wrong-answer cause.
- Including the middle-side cells, turning the hourglass into a full block sum.
Practice
Try the solution yourself
Edit the optimal implementation, test another input, and observe the result.
Editable code previewpublic int hourglassSum(int[][] arr) { int best = Integer.MIN_VALUE; for (int r = 0; r + 2 < arr.length; r++) { for (int c = 0; c + 2 < arr[r].length; c++) { int sum = arr[r][c] + arr[r][c + 1] + arr[r][c + 2]Explore the playgroundClose the playground
Avoid mistakes
Recognize the interview traps
Understand why common attempts fail before reviewing the corrected implementation.
1Zero-initialized maximum
On a grid where every hourglass sum is negative, starting at 0 returns 0 — a value that no hourglass actually produces.
Explore the code comparisonHide the code comparison
Zero-initialized maximum
On a grid where every hourglass sum is negative, starting at 0 returns 0 — a value that no hourglass actually produces.
Don't write this
int best = 0;
// ... best = Math.max(best, sum);Write this instead
int best = Integer.MIN_VALUE;
// ... best = Math.max(best, sum);2Out-of-bounds corner range
Running the corner over 0..5 makes arr[r+2] reach index 7 — an ArrayIndexOutOfBoundsException.
Explore the code comparisonHide the code comparison
Out-of-bounds corner range
Running the corner over 0..5 makes arr[r+2] reach index 7 — an ArrayIndexOutOfBoundsException.
Don't write this
for (int r = 0; r <= 5; r++) {
for (int c = 0; c <= 5; c++) {
int sum = arr[r + 2][c + 2] + /* ... */;
}
}Write this instead
for (int r = 0; r + 2 < arr.length; r++) {
for (int c = 0; c + 2 < arr[r].length; c++) {
int sum = arr[r + 2][c + 2] + /* ... */;
}
}3Summing the full block
Adding arr[r+1][c] and arr[r+1][c+2] turns the hourglass into a 9-cell square and overcounts.
Explore the code comparisonHide the code comparison
Summing the full block
Adding arr[r+1][c] and arr[r+1][c+2] turns the hourglass into a 9-cell square and overcounts.
Don't write this
s = sum(arr[r + dr][c + dc] for dr in range(3) for dc in range(3))Write this instead
s = (arr[r][c] + arr[r][c+1] + arr[r][c+2]
+ arr[r+1][c+1]
+ arr[r+2][c] + arr[r+2][c+1] + arr[r+2][c+2])Revise
Carry the pattern into the interview
Pattern to remember
Fixed-size mask slid over a bounded grid
Code pattern to memorize
for r in 0..3:
for c in 0..3:
top = g[r][c] + g[r][c+1] + g[r][c+2]
mid = g[r+1][c+1]
bottom = g[r+2][c] + g[r+2][c+1] + g[r+2][c+2]
best = max(best, top + mid + bottom)Rules to remember
- 1There are exactly 16 hourglasses in a 6×6 grid: 4 valid top rows × 4 valid left columns.
- 2Initialize
bestto a very negative value, not0— sums can be negative when all 7 cells are negative. - 3The hourglass is not a full 3×3 block. The two middle-side cells
g[r+1][c]andg[r+1][c+2]are excluded. - 4Iterate the top-left corner only over rows
0..3and columns0..3sor+2andc+2stay in bounds. - 5Sum the 7 cells directly — there's no benefit to a prefix-sum here because the mask is tiny and fixed.
Use this pattern when
- A fixed-shape stencil (hourglass, plus, cross) slides over a bounded grid
- The grid dimensions are constant, so total work is a constant number of fixed-cost sums
- You need the max/min of a small fixed pattern over every legal position
Choose another pattern when
- The window is a variable-size rectangle whose sum changes incrementally → 2D prefix sums
- You need every subrectangle sum, not one fixed shape → integral image
- The grid is huge and the mask is large → precompute partial sums instead of re-summing
Interview takeaway
When a fixed-shape mask slides over a bounded grid, the whole problem is 'enumerate every legal top-left corner, sum the masked cells, keep the best'. The only traps are the bounds (16 positions, not 36) and the negative-init for `best`.
Continue
Transfer the pattern to another problem
Use a direct variation or pattern sibling to prove the idea is reusable.
Transferable patternFixed-shape mask over a bounded grid. Enumerate every legal top-left corner, sum the masked cells, keep the best. The recurring traps are the bounds (count the valid corners) and the negative initialization. Generalizes to plus/cross stencils and to n×n grids.
Practice queueDirect variations and pattern siblings
Direct follow-ups