Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Move from brute-force thinking to an efficient approach using array strategy.
Given a positive integer n, generate an n x n matrix filled with elements from 1 to n2 in spiral order.
Example 1:
Input: n = 3 Output: [[1,2,3],[8,9,4],[7,6,5]]
Example 2:
Input: n = 1 Output: [[1]]
Constraints:
1 <= n <= 20Problem summary: Given a positive integer n, generate an n x n matrix filled with elements from 1 to n2 in spiral order.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array
3
1
spiral-matrix)spiral-matrix-iii)spiral-matrix-iv)class Solution {
public int[][] generateMatrix(int n) {
int[][] ans = new int[n][n];
int top = 0, bottom = n - 1;
int left = 0, right = n - 1;
int value = 1;
while (top <= bottom && left <= right) {
for (int c = left; c <= right; c++) ans[top][c] = value++;
top++;
for (int r = top; r <= bottom; r++) ans[r][right] = value++;
right--;
if (top <= bottom) {
for (int c = right; c >= left; c--) ans[bottom][c] = value++;
bottom--;
}
if (left <= right) {
for (int r = bottom; r >= top; r--) ans[r][left] = value++;
left++;
}
}
return ans;
}
}
func generateMatrix(n int) [][]int {
ans := make([][]int, n)
for i := 0; i < n; i++ {
ans[i] = make([]int, n)
}
top, bottom := 0, n-1
left, right := 0, n-1
value := 1
for top <= bottom && left <= right {
for c := left; c <= right; c++ {
ans[top][c] = value
value++
}
top++
for r := top; r <= bottom; r++ {
ans[r][right] = value
value++
}
right--
if top <= bottom {
for c := right; c >= left; c-- {
ans[bottom][c] = value
value++
}
bottom--
}
if left <= right {
for r := bottom; r >= top; r-- {
ans[r][left] = value
value++
}
left++
}
}
return ans
}
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
ans = [[0] * n for _ in range(n)]
top, bottom = 0, n - 1
left, right = 0, n - 1
value = 1
while top <= bottom and left <= right:
for c in range(left, right + 1):
ans[top][c] = value
value += 1
top += 1
for r in range(top, bottom + 1):
ans[r][right] = value
value += 1
right -= 1
if top <= bottom:
for c in range(right, left - 1, -1):
ans[bottom][c] = value
value += 1
bottom -= 1
if left <= right:
for r in range(bottom, top - 1, -1):
ans[r][left] = value
value += 1
left += 1
return ans
impl Solution {
pub fn generate_matrix(n: i32) -> Vec<Vec<i32>> {
let n = n as usize;
let mut ans = vec![vec![0; n]; n];
let mut top: i32 = 0;
let mut bottom: i32 = n as i32 - 1;
let mut left: i32 = 0;
let mut right: i32 = n as i32 - 1;
let mut value = 1;
while top <= bottom && left <= right {
for c in left..=right {
ans[top as usize][c as usize] = value;
value += 1;
}
top += 1;
for r in top..=bottom {
ans[r as usize][right as usize] = value;
value += 1;
}
right -= 1;
if top <= bottom {
for c in (left..=right).rev() {
ans[bottom as usize][c as usize] = value;
value += 1;
}
bottom -= 1;
}
if left <= right {
for r in (top..=bottom).rev() {
ans[r as usize][left as usize] = value;
value += 1;
}
left += 1;
}
}
ans
}
}
function generateMatrix(n: number): number[][] {
const ans: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
let top = 0;
let bottom = n - 1;
let left = 0;
let right = n - 1;
let value = 1;
while (top <= bottom && left <= right) {
for (let c = left; c <= right; c++) ans[top][c] = value++;
top++;
for (let r = top; r <= bottom; r++) ans[r][right] = value++;
right--;
if (top <= bottom) {
for (let c = right; c >= left; c--) ans[bottom][c] = value++;
bottom--;
}
if (left <= right) {
for (let r = bottom; r >= top; r--) ans[r][left] = value++;
left++;
}
}
return ans;
}
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.