开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 8 天,点击查看活动详情
59.螺旋矩阵II
给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
自做——左开右闭
还是自己先写了一遍,一般我做这种题会用一点点特殊值法,因为硬想那种很抽象的我也想不出来,所以就拿题目中那个例子当特殊值来假设设计边界条件。先写出一个大体思路,然后再一点点改逻辑不对的点,经常出错的地方无非就那几个,比如是用大于等于还是大于,是n-1还是n等等。
class Solution {
public int[][] generateMatrix(int n) {
int[][] matrix=new int[n][n];
int i=0,j=0,num=1;
for(int k=0;k<n;k++){
for(j=k;j<n-k;j++){
matrix[i][j]=num++;
}
j--;
for(i=k+1;i<n-k;i++){
matrix[i][j]=num++;
}
i--;
for(j=n-k-2;j>=k;j--){
matrix[i][j]=num++;
}
j++;
for(i=n-k-2;i>=k+1;i--){
matrix[i][j]=num++;
}
i++;
}
return matrix;
}
}
这里有一个易错的点我个人认为除了边界条件就是四个角,这四个角稍不注意可能就会重复赋值,所以我是这样做的:
四个边都用一道规则,算尾不算头,也就是左开右闭(除了第一次第一行),就比如第一行全算上,然后对最后一列赋值时就直接从第二个元素开始,因为第一个元素刚才第一行已经赋值过了,然后到最后一行就从倒数第二个元素开始而不是倒数第一个,依此类推。
但是经过学习后,发现我这个方法并不好,思路也略显混乱,四条边规则仍然不算统一,左闭右开才算统一,所以接下来我们一起看看更优解
左闭右开
整体采用构建矩阵,填充矩阵的思路,填充过程分为四种情况:
- 从左到右填充一行
- 从上到下填充一列
- 从右到左填充一行,注意只有一行的情况
- 从下到上填充一列,注意只有一列的情况
就这样从外圈到内圈一圈一圈画下去
class Solution {
public int[][] generateMatrix(int n) {
int start=0,offset=0;
int[][] matrix=new int[n][n];
int i,j,num=1;
while(offset++< n/2){
for(j=start;j<n-offset;j++){
matrix[start][j]=num++;
}
for(i=start;i<n-offset;i++){
matrix[i][j]=num++;
}
for(;j>=offset;j--){
matrix[i][j]=num++;
}
for(;i>=offset;i--){
matrix[i][j]=num++;
}
start++;
}
if(n%2!=0){
matrix[start][start]=num;
}
return matrix;
}
}
后来在力扣题解中看到另一种写法,设定上下左右边界,思路很清晰
看了这么多种解法,我的结论是大差不差,只要把模拟矩阵的思路搞清晰了,自己想明白了,其实写起来也不是那么的难,只是可怜了那本就不多的几根头发