螺旋矩阵--力扣59--螺旋矩阵||

目录

题目

思路

代码


题目

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

示例 1:

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]

示例 2:

输入:n = 1
输出:[[1]]

思路

相当于是一个绕正方形,首先弄明白环绕方式,然后它的关键在于正方形四个角的处理。

想法遵循二分法的循环不变量原则。我们选择第一行从左到右,接着从上到下,再从右到左,最后从下到上;一层循环结束后进行第二层......这里采用左闭右开,就是有四个角,每一行都是包含开头那个角,另外一个角等处理旁边那条边的时候再进行,这样有一个规则就不会弄混了。

同一个颜色代表同一次处理

代码

class Solution {
    public int[][] generateMatrix(int n) {
int starty=0,startx=0;//把他想成一个数组的排列,有x有y,startx表示行的第一个,starty表示列的第一个
int i,j;//通常我们习惯把数组表示成a[i][j],所以这里i表示行,j表示列
int offset=0;//这个表示循环次数
int count=1;//因为这个数组排列是从1到n的平方,所以我们这里是1
int [][] res=new int [n][n];//定义一个数组让他是一个正方形
while(offset++<n/2){//这里要先加,不能offset赋值为0然后这里直接进循环后面才++,这样会造成正方形角计算的混乱,以及为什么是n/2,画一个图就知道了,它表示的是循环的次数
for(j=starty;j<n-offset;j++){//这是第一行从左到右,j从列的第一个开始,然后第一个元素的索引是0,假如n为4,那么最后那个数字的索引为3,然而不能包括这个数字(原因在思路中),所以这里是n-offset,offset为1,j++让它往后移遍历
res[startx][j]=count++;//这里startx为0,就表示给第一行的赋值了
//最后这里结束是j指向一行中最后一个元素
}
for(i=startx;i<n-offset;i++){//这是从上到下的情况,i从第一行开始,然后情况同上一个
    res[i][j]=count++;//上一个for中j指向一行中最后一个元素,所以这里直接给[i][j]赋值了
//这里结束时i指向的是最后一列最后一行的元素
}
for(;j>=offset;j--){//这是从后往前的情况,由于第一次循环j指向一行中最后一个元素,所以这里不需要再给初始值了,然后要包括最后一行的第一个元素,所以是>=
    res[i][j]=count++;
}for(;i>=offset;i--){//这是从下往上的情况,由于循环i指向的是最后一行的元素,所以这里不需要再给初始值,其余同上
    res[i][j]=count++;
}
//到这里第一圈的循环就结束了但是它可能会有第二圈,第二圈时列和行的起始位置都需要改变,以及减的offset也是,所以再次进入循环
starty++;
startx++;
}
if (n % 2 == 1) {//如果给的n为奇数,最后剩下的是最中间的元素,直接给他赋值即可
            res[startx][starty] = count;
        }
        return res;
    }
}

注意:

为啥循环是:

for(;j>=offset;j--)而不是>=starty呢

>=offset就不会包括那个最后一行第一个角了(也就是示例中数字7的位置),这样遵循了循环不变量原则,然而如果是另外一种情况的话,拿第一圈循环为例,相当于是>=0,这同样会包括它,就违背了这个原则

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值