算法--数组--螺旋矩阵 II
给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
1 解答
先写再看噢~
解答
这个讲得很详细👉代码随想录
1.1 思路
// 思路比较简单,两个指针,一个指针走到底,换另一个走,j++, i++, j--, i--
// 但是用 while 循环,每次都会从第一个 if 开始判断,就得控制走到对的if判断里,用 n=3,4,5,的试,往往是这个条件加上,这一圈符合了,下一圈又走不对了
// 尝试中👇
const generateMatrix = function (n) {
const array = new Array(n).fill(0).map(() => new Array(n).fill(0));
let i = 0;
let j = 0;
let k = 1;
while (k <= n * n) {
array[i][j] = k;
k++;
if (j < n - 1 && i < n / 2) {
// 上行从左到右
if (!array[i][j + 1]) {
j++;
} else if (i > 0) {
i++;
}
} else if (i < n - 1 && j > n / 2) {
// 右列从上到下
if (!array[i + 1][j]) {
i++;
} else if (j > 0) {
j--;
}
} else if (j > 0 && i >= n / 2) {
// 下行从右到左
if (!array[i][j - 1]) {
j--;
} else if (i < n - 1) {
i--;
}
} else if (i > 0 && j <= n / 2) {
// 左列从下到上
if (!array[i - 1][j]) {
i--;
} else if (j < n - 1) {
j++;
}
}
}
return array;
};
1.2 优化
自己控制起点终点
const generateMatrix = function (n) {
const array = new Array(n).fill(0).map(() => new Array(n).fill(0));
let i = 0;
let j = 0;
let k = 1; // 值
let loop = 0; // 圈数
while (k <= n * n) {
let startI = loop; // 每圈i的最小值
let endI = n - 1 - loop; // 每圈i的最大值
let startJ = loop; // 每圈j的最小值
let endJ = n - 1 - loop; // 每圈j的最大值
if (0 + loop === n - 1 - loop) {
array[loop][loop] = k++; // 起点等于终点,最中间的赋值
break;
} else if (0 + loop > n - 1 - loop) {
break;
}
// 上行从左到右(左闭右开)
i = startI;
for (j = startJ; j <= endJ - 1; j++) {
array[i][j] = k++;
}
// 右列从上到下(左闭右开)
j = endJ;
for (i = startI; i <= endI - 1; i++) {
array[i][j] = k++;
}
// 下行从右到左(左闭右开)
i = endI;
for (j = endJ; j >= startJ + 1; j--) {
array[i][j] = k++;
}
// 左列从下到上(左闭右开)
j = startJ;
for (i = endI; i >= startI + 1; i--) {
array[i][j] = k++;
}
loop++; // 圈数增加
}
return array;
};
时间复杂度 o(n^2) 空间复杂度 o(n^2)
1.3 优化
/**
* @param {number} n
* @return {number[][]}
*/
var generateMatrix = function (n) {
let startX = (startY = 0); // 起始位置
let loop = Math.floor(n / 2); // 旋转圈数
let mid = Math.floor(n / 2); // 中间位置
let offset = 1; // 控制每一层填充元素个数
let count = 1; // 更新填充数字
let res = new Array(n).fill(0).map(() => new Array(n).fill(0));
while (loop--) {
let row = startX,
col = startY;
// 上行从左到右(左闭右开)
for (; col < startY + n - offset; col++) {
res[row][col] = count++;
}
// 右列从上到下(左闭右开)
for (; row < startX + n - offset; row++) {
res[row][col] = count++;
}
// 下行从右到左(左闭右开)
for (; col > startY; col--) {
res[row][col] = count++;
}
// 左列做下到上(左闭右开)
for (; row > startX; row--) {
res[row][col] = count++;
}
// 更新起始位置
startX++;
startY++;
// 更新offset
offset += 2;
}
// 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
if (n % 2 === 1) {
res[mid][mid] = count;
}
return res;
};