题目描述
给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3
输出:
[
[ 1, 2, 3 ],
[ 8, 9, 4 ],
[ 7, 6, 5 ]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/spiral-matrix-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路分析
顺时针螺旋排矩阵解决步骤如下:
每画一个边界正方形需要:—不断循环该步骤。画出矩阵
- 最上行从左向右
- 最右行从上到下
- 最下行从右到左
- 最左行 从下到上
**注意:**在进行以上4个循环时,条件的判断,坚持循环不变量原则
循环该步骤判断条件:
- 根据n计算出需要几个圈loop:n/2
- 或者:每次填充矩阵的count<=n*n
若是奇数,在最*位置n*n
代码如下:
class Solution {
public int[][] generateMatrix(int n) {
int[][] result = new int[n][n];
int loop=n/2; //需要循环填充几个圈
int startx=0,starty=0;//每个圈的起始位置
int mid=n/2; //中间位置
int count=1; // 给每一个元素赋值用
int offset=1; //给每次循环长度改变
int i,j;
while(loop-->0){ //填充一个圈
i=startx;j=starty;
//最上边 从左向右 [starty,starty+n-offset)
for(j = starty; j < starty + n - offset; j++){//循环遍历长度需要变
result[i][j] = count++;
}
//最右边从上到下[,)
for(i = startx; i < startx + n - offset; i++){
result[i][j] = count++;
}
//最下边 从右到左
for(; j > starty; j--){//循环遍历长度需要变
result[i][j] = count++;
}
//最左边 从下到上
for(;i>startx;i--){
result[i][j]=count++;
}
offset+=2;
startx++;
starty++;
}
if(n%2 == 1) {
result[mid][mid]=n*n;
}
return result;
}
}
解决思路:限定边界
思路见代码:
class Solution {
public int[][] generateMatrix(int n) {
// int[][] result = new int[n][n];
// int loop=n/2; //需要循环填充几个圈
// int startx=0,starty=0;//每个圈的起始位置
// int mid=n/2; //中间位置
// int count=1; // 给每一个元素赋值用
// int offset=1; //给每次循环长度改变
// int i,j;
// while(loop-->0){ //填充一个圈
// i=startx;j=starty;
// //最上边 从左向右
// for(j = starty; j < starty + n - offset; j++){//循环遍历长度需要变
// result[i][j] = count++;
// }
// //最右边从上到下
// for(i = startx; i < startx + n - offset; i++){
// result[i][j] = count++;
// }
// //最下边 从右到左
// for(; j > starty; j--){//循环遍历长度需要变
// result[i][j] = count++;
// }
// //最左边 从下到上
// for(;i>startx;i--){
// result[i][j]=count++;
// }
// offset+=2;
// startx++;
// starty++;
// }
// if(n%2 == 1) {
// result[mid][mid]=n*n;
// }
// return result;
/*
控制边界方法:
设定上、下、左、右的边界
从左到右
从上到下
从右到左
从下到上
更新边界
-->更新上边界
-->更新右边界
-->更新下边界
-->更新左边界
*/
int result[][] = new int[n][n];
int count = 1; // 用来填充矩阵中的每一个元素
int end = n*n;
int up=0,right=n-1,down=n-1,left=0;
int mid=n/2;
// while(count <= end){
// // 四个for循环进行填充 左闭右开 当n为奇数时无法填充最后一个元素 改为左闭右闭区间
// for(int i = left; i < right; i++) {result[up][i] = count++;} //上:左-->右
// for(int j = up; j < down; j++) {result[j][right] = count++;} //右:上-->下
// for(int i = right; i > left; i--) {result[down][i] = count++;} //下:右-->左
// for(int j = down; j > up; j--) {result[j][left] = count++;} //左:下-->上
// //更新边界
// up++;right--;down--;left++;
// }
while(count <= end){
// 四个for循环进行填充 改为:左闭右闭区间 更新边界需要在每一次for循环后
for(int i = left; i <= right; i++) {result[up][i] = count++;} //上:左-->右
up++;
for(int j = up; j <= down; j++) {result[j][right] = count++;} //右:上-->下
right--;
for(int i = right; i >= left; i--) {result[down][i] = count++;} //下:右-->左
down--;
for(int j = down; j >= up; j--) {result[j][left] = count++;} //左:下-->上
left++;
}
return result;
}
}