I got this question during my practice interview.
Matrices - N Spiral Matrix
Prompt
Given an integer N, output an N x N spiral matrix with integers 1 through N.
Examples:
Input: 3
Output: [[1, 2, 3],
[8, 9, 4],
[7, 6, 5]]
Input: 1
Output: [[1]]
My solution is below:
function spiralMatrix(n) {
const matrix = [];
let counter = 1,
rowMin = 0,
rowMax = n - 1,
colMin = 0,
colMax = n - 1;
for (let i = 0; i < n; i++) {
matrix.push(new Array(n).fill(0));
}
while (rowMin <= rowMax && colMin <= colMax) {
for (let col = colMin; col <= colMax; col++) {
matrix[rowMin][col] = counter++;
}
rowMin++;
for (let row = rowMin; row <= rowMax; row++) {
matrix[row][colMax] = counter++;
}
colMax--;
for (let col = colMax; col >= colMin; col--) {
matrix[rowMax][col] = counter++;
}
rowMax--;
for (let row = rowMax; row >= rowMin; row--) {
matrix[row][colMin] = counter++;
}
colMin++;
}
return matrix;
}
console.log(spiralMatrix(10));
3 Answers 3
This code is well written;
Comments
- You have no comments whatsoever, fortunately the code reads well
JSHint.com
- Your code passes all checks, well done
Nice code. I have just one nitpick.
No need to declare all variables at the top of a function.
It's good to declare variables right before they are used.
In the posted code, the filling of matrix
could go directly after its declaration,
and the rest of the variables could be declared right before the loop that uses them.
I mean like this:
const matrix = [];
for (let i = 0; i < n; i++) {
matrix.push(new Array(n).fill(0));
}
let counter = 1,
rowMin = 0,
rowMax = n - 1,
colMin = 0,
colMax = n - 1;
while (rowMin <= rowMax && colMin <= colMax) {
// ...
-
\$\begingroup\$ Do you have any references that say it is good to declare variables right before they are used? This does not seem to follow any major coding styles guide. \$\endgroup\$konijn– konijn2019年02月22日 16:52:58 +00:00Commented Feb 22, 2019 at 16:52
-
\$\begingroup\$ @konijn the book Code Complete takes about span and live time of variables. See it explained here: nikola-breznjak.com/blog/books/programming/… . Keeping these numbers low mitigates the mental burden for readers. \$\endgroup\$janos– janos2019年02月22日 17:20:42 +00:00Commented Feb 22, 2019 at 17:20
Rather than use row
, and col
, it is common to index a 2D array with x
and y
. x
is column and y
is row.
Rather than use for
loops, you can reduce the noise using while
loops inside the main loop.
The main exit condition is a little complex. You are counting the values with counter
so why not just check its value while(counter < n ** 2) {
colMax
and rowMax
can be combined to just one value, same with colMin
, and rowMin
The overhead of creating and filling each array before you start is negating the benefit of avoiding sparse arrays. The code would be simpler if you just push an array literal rather then a new n item array filled with 0.
Thus you end up with
function spiralMatrix(n) {
var c = 1, min = 0, max = n - 1, x = 0, y = 0;
const matrix = [];
for (let i = 0; i < n; i++) { matrix.push([]) }
while (c < n ** 2) {
while (x < max) { matrix[y][x++] = c++ }
while (y < max) { matrix[y++][x] = c++ }
while (x > min) { matrix[y][x--] = c++ }
min++;
while (y > min) { matrix[y--][x] = c++ }
max--;
}
matrix[y][x] = c;
return matrix;
}
Explore related questions
See similar questions with these tags.