Given an integer n, generate a square matrix filled with elements from 1 to n^2 in spiral order. For example, given n = 4,
[ [1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7] ]
Java Solution 1
public int[][] generateMatrix(int n) { int total = n*n; int[][] result= new int[n][n]; int x=0; int y=0; int step = 0; for(int i=0;i<total;){ while(y+step<n){ i++; result[x][y]=i; y++; } y--; x++; while(x+step<n){ i++; result[x][y]=i; x++; } x--; y--; while(y>=0+step){ i++; result[x][y]=i; y--; } y++; x--; step++; while(x>=0+step){ i++; result[x][y]=i; x--; } x++; y++; } return result; } |
Java Solution 2
public int[][] generateMatrix(int n) { int[][] result = new int[n][n]; int k=1; int top=0; int bottom=n-1; int left=0; int right=n-1; while(k<=n*n){ for(int i=left; i<=right; i++){ result[top][i]=k; k++; } top++; for(int i=top; i<=bottom; i++){ result[i][right]=k; k++; } right--; for(int i=right; i>=left; i--){ result[bottom][i]=k; k++; } bottom--; for(int i=bottom; i>=top; i--){ result[i][left] = k; k++; } left++; } return result; } |
A simpler and clean solution based on previous code.
public class SpiralMatrixNumbered {
public static void main(String[] args) {
int n1=4;
int m=n1;//columns
int n=n1;//rows
int arr[][]=new int[m][n];
int x=0,y=0;
int num=1;
while(m>0 && n>0){
if(m==1){
for(int i=0;i<n;i++){
arr[x][y]=num;
num++;
y++;
}
}else if(n==1){
for(int i=0;i<m;i++){
arr[x][y]=num;
num++;
x++;
}
}
for(int i=0;i<m-1;i++){
arr[x][y]=num;
y++;
num++;
}
for(int i=0;i<n-1;i++){
arr[x][y]=num;
x++;
num++;
}
for(int i=0;i<m-1;i++){
arr[x][y]=num;
y--;
num++;
}
for(int i=0;i<n-1;i++){
arr[x][y]=num;
x--;
num++;
}
x++;
y++;
m=m-2;
n=n-2;
}
}
}
The following is another solution using recursion, which is based on one of the solutions provided for Spiral Matrix 1:
void spiral(final int rows, final int cols) {
final int[][] matrix = new int[rows][cols];
spiralRecurse(matrix, 0, 0, rows, cols, 0);
// stdOut the matrix
}
private void spiralRecurse(final int[][] matrix, int currentRow, int currentCol, int rows, int cols, int value) {
if (rows <= 0 || cols <= 0) {
return;
}
//only one element left
if (rows == 1 && cols == 1) {
matrix[currentRow][currentCol] = ++value;
return;
}
//Top side: Move from left to right
for (int idx = 0; idx < cols - 1; idx++) {
matrix[currentRow][currentCol++] = ++value;
}
//Right side: Move from top to bottom
for (int idx = 0; idx < rows - 1; idx++) {
matrix[currentRow++][currentCol] = ++value;
}
//Bottom side: Move from right to left
for (int idx = 0; idx < cols - 1; idx++) {
matrix[currentRow][currentCol--] = ++value;
}
//Left side: Move from bottom to top
for (int idx = 0; idx < rows - 1; idx++) {
matrix[currentRow--][currentCol] = ++value;
}
// By the time we reached here, we finished walking the external 'circle',
// the currentRow & currentCol are back to zeroes.
//
// Now, we want to start walking the next inner circle, by incrementing
// currentRow & currentCol and adjusting the matrix limits
spiralRecurse(matrix, currentRow + 1, currentCol + 1, rows - 2, cols - 2, value);
}
Similar but probably little more simple to read. Accepted in leetcode.
public class Solution {
public int[][] generateMatrix(int n) {
int[][] ret = new int[n][n];
int x=0,y=0;
int step=1;
for(int i=1;i<=n*n;){
if(i==n*n){
ret[x][y] = i;
break;
}
while(y<n-step){
ret[x][y++] = i++;
}
while(x=0+step){
ret[x][y--] = i++;
}
while(x>=0+step){
ret[x--][y] = i++;
}
x++;
y++;
step++;
}
return ret;
}
}