Generate a Spiral Matrix
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
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.
/*
* 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)
- Why do we check top <= bottom before the bottom row?
- How many rings are there?