* Matrix - Spiral Traversal Pre Update
* Array - Ignore Auxilary Space O(ROWS * COLS)
* Time O(ROWS * COLS) | Space O(1)
* https://leetcode.com/problems/spiral-matrix/
* @param {number[][]} matrix
* @return {number[]}
*/
var spiralOrder = function (matrix, order = []) {
const [rows, cols] = [matrix.length - 1, matrix[0].length - 1];
let [top, bot, left, right] = [0, rows, 0, cols];
const isInBounds = () => left <= right && top <= bot;
while (isInBounds()) {
addTop(
matrix,
top,
bot,
left,
right,
order,
);
top++;
addRight(
matrix,
top,
bot,
left,
right,
order,
);
right--;
const hasRow = top <= bot;
if (hasRow) {
addBot(
matrix,
top,
bot,
left,
right,
order,
);
bot--;
}
const hasCol = left <= right;
if (hasCol) {
addLeft(
matrix,
top,
bot,
left,
right,
order,
);
left++;
}
}
return order;
};
var addTop = (matrix, top, bot, left, right, order) => {
for (let col = left; col <= right; col++) {
order.push(
matrix[top][col],
);
}
};
var addRight = (matrix, top, bot, left, right, order) => {
for (let row = top; row <= bot; row++) {
order.push(
matrix[row][right],
);
}
};
var addBot = (matrix, top, bot, left, right, order) => {
for (let col = right; left <= col; col--) {
order.push(
matrix[bot][col],
);
}
};
var addLeft = (matrix, top, bot, left, right, order) => {
for (let row = bot; top <= row; row--) {
order.push(
matrix[row][left],
);
}
};
* Matrix - Spiral Traversal Post Update
* Array - Ignore Auxilary Space O(ROWS * COLS)
* Time O(ROWS * COLS) | Space O(1)
* https://leetcode.com/problems/spiral-matrix/
* @param {number[][]} matrix
* @return {number[]}
*/
var spiralOrder = (matrix, order = []) => {
const [rows, cols] = [matrix.length, matrix[0].length];
const cells = rows * cols;
let [top, bot, left, right] = [0, rows - 1, 0, cols - 1];
while (order.length < cells) {
traverse(
matrix,
top,
bot,
left,
right,
order,
);
top++;
bot--;
left++;
right--;
}
return order;
};
var traverse = (matrix, top, bot, left, right, order) => {
addTop(
matrix,
top,
bot,
left,
right,
order,
);
addRight(
matrix,
top,
bot,
left,
right,
order,
);
addBot(
matrix,
top,
bot,
left,
right,
order,
);
addLeft(
matrix,
top,
bot,
left,
right,
order,
);
};
var addTop = (matrix, top, bot, left, right, order) => {
for (let col = left; col <= right; col++) {
order.push(
matrix[top][col],
);
}
};
var addRight = (matrix, top, bot, left, right, order) => {
for (let row = top + 1; row <= bot; row++) {
order.push(
matrix[row][right],
);
}
};
var addBot = (matrix, top, bot, left, right, order) => {
for (let col = right - 1; left <= col; col--) {
const isOutOfBounds = top === bot;
if (isOutOfBounds) return;
order.push(
matrix[bot][col],
);
}
};
var addLeft = (matrix, top, bot, left, right, order) => {
for (let row = bot - 1; row >= top + 1; row--) {
const isOutOfBounds = left === right;
if (isOutOfBounds) return;
order.push(
matrix[row][left],
);
}
};
* Matrix - Mark Visited In Place
* Array - Ignore Auxilary Space O(ROWS * COLS)
* Time O(ROWS * COLS) | Space O(1)
* https://leetcode.com/problems/spiral-matrix/
* @param {number[][]} matrix
* @return {number[]}
*/
var spiralOrder = (matrix) => {
const order =
initOrder(
matrix,
);
spiral(
matrix,
order,
);
return order;
};
const initOrder = (matrix, VISITED = 101) => {
const order = [matrix[0][0]];
matrix[0][0] = VISITED;
return order;
};
var spiral = (matrix, order) => {
let [row, col, direction, changeDirection] = [0, 0, 0, 0];
while (changeDirection < 2) {
[row, col, direction, changeDirection] =
getPointers(matrix, row, col, direction, changeDirection, order);
}
};
const getPointers = (matrix, row, col, direction, changeDirection, order) => {
[row, col, direction, changeDirection] =
move(matrix, row, col, direction, changeDirection, order);
direction = (direction + 1) % 4;
changeDirection += 1;
return [row, col, direction, changeDirection];
};
const move = (
matrix,
row,
col,
direction,
changeDirection,
order,
VISITED = 101,
) => {
const [rows, cols] = [matrix.length, matrix[0].length];
while (canMove(matrix, row, rows, col, cols, direction)) {
[row, col] = getCell(row, col, direction);
order.push(
matrix[row][col],
);
matrix[row][col] = VISITED;
changeDirection = 0;
}
return [row, col, direction, changeDirection];
};
const canMove = (matrix, row, rows, col, cols, direction) => {
if (!isInBounds(row, rows, col, cols, direction)) return false;
return !hasSeen(matrix, row, col, direction);
};
const isInBounds = (row, rows, col, cols, direction) => {
const [_row, _col] = getCell(row, col, direction);
const isRowInBounds = 0 <= _row && _row < rows;
const isColInBounds = 0 <= _col && _col < cols;
return isRowInBounds && isColInBounds;
};
const hasSeen = (matrix, row, col, direction, VISITED = 101) => {
const [_row, _col] = getCell(row, col, direction);
return matrix[_row][_col] === VISITED;
};
const getDirection = (direction) => {
const directions = [
[0, 1],
[1, 0],
[0, -1],
[-1, 0],
];
return directions[direction];
};
const getCell = (row, col, direction) => {
const [_row, _col] = getDirection(direction);
return [row + _row, col + _col];
};