Generate a Spiral Matrix

medium Matrix (2D arrays)

Problem

Fill an n by n grid with the numbers 1 to n * n in a clockwise spiral that starts at the top-left cell and moves right first. Print the grid, one row per line, numbers separated by spaces.

Constraints

  • 1 <= n <= 20

Examples

Input

3

Output

1 2 3
8 9 4
7 6 5

Solutions

Best approachTime O(n^2)Space O(n^2)

Each loop fills one full ring of the spiral. After a ring, the four borders move inward. The two if checks stop a thin last ring from being filled twice.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Spiral fill.
 * Input   : n.
 * Output  : n rows.
 * Approach: Shrinking borders.
 * Time    : O(n^2)
 * Space   : O(n^2)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
    // This method solves the task. It receives the input and returns the answer.
    static String[] solve(long n) {
        // Step 1: Four borders mark the part of the grid that is still empty.
        int size = (int) n;
        int[][] grid = new int[size][size];
        int top = 0;
        int bottom = size - 1;
        int left = 0;
        int right = size - 1;
        int value = 1;
        while (top <= bottom && left <= right) {
            // Step 2: Fill the top row, the right column, the bottom row and the left column. Then move all borders inward.
            for (int j = left; j <= right; j++) {
                grid[top][j] = value++;
            }
            top++;
            for (int i = top; i <= bottom; i++) {
                grid[i][right] = value++;
            }
            right--;
            if (top <= bottom) {
                for (int j = right; j >= left; j--) {
                    grid[bottom][j] = value++;
                }
                bottom--;
            }
            if (left <= right) {
                for (int i = bottom; i >= top; i--) {
                    grid[i][left] = value++;
                }
                left++;
            }
        }
        String[] lines = new String[size];
        for (int i = 0; i < size; i++) {
            StringBuilder row = new StringBuilder();
            for (int j = 0; j < size; j++) {
                row.append(j == 0 ? "" : " ").append(grid[i][j]);
            }
            lines[i] = row.toString();
        }
        return lines;
    }

    public static void main(String[] args) {
        long n = new Scanner(System.in).nextLong();
        System.out.println(String.join("\n", solve(n)));
    }
}
Hints (2)
  1. Why do we check top <= bottom before the bottom row?
  2. How many rings are there?