做题总结 59. 螺旋矩阵 II

本文讲述了作者在使用Java实现一个生成包含1到n^2元素、按顺时针排列的nxn正方形矩阵过程中遇到的问题,包括缺失返回值、边界处理错误、循环次数计算失误以及for循环逻辑错误,详细分析并给出了修正方法。

跟着代码随想录顺序到这题,不会做。不知道怎么才能实现。
PS:我是用 java实现的。

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

总结思路为:

二维数组实现+保存结果。顺时针处理,看作处理四条边,四个for循环。
注意边界问题。

实现代码的时候犯的错:

(1)没有返回值

添加 return matrix;

(2)四周绕一圈处理值之后,n为奇数的时候最中间的值没有处理。

跳出循环后:

if(n % 2 == 1) {//奇数条件的限制
   matrix[start][start] = num++;
}

这里要添加奇数条件的限制。如果没有 if 条件,当n为偶数时也会改变值。

(3)循环次数出错

分析:n=3时,绕一圈即可。n=4时,绕两圈。所以循环的次数为 n/2。
但是写while循环的时候出错了,出错的原因是,忘记 自增运算符的优先级比不等号大

本来写的是 int loop = n/2; while(loop-- >= 0) 但是这样是不对的,因为会先判断是否大于等于0,然后进入循环,再对 loop进行减一操作。修改为while(--loop >= 0)

更直观一点,跟代码随想录中一样,int loop = 0; while (loop++ < n / 2) 这个的好处是,很直观看出循环次数和 n 之间的关系。加法相比减法也不容易出错。而且卡尔哥合并了 offset 和 loop的作用,是需要通过加法保持两者的一致性的。

(4)四个for循环都写错了

天哪,错误实在太多了。整个自己写的代码好像一句话都没对啊。。。
关键点在,顺时针处理的时候,顺序为 上->右->下->左,要清楚每一条边那个条件是不变的。比如处理 “上” 边的时候,它的纵坐标是不会变的!

(5)循环中处理边的 i j 是可以不变的

我是这么写的:

//top
for(int j=start; j<n-offset; j++) {
    matrix[start][j] = num++;
}

//right
for(int i=start; i<n-offset; i++) {
    matrix[i][n-offset] = num++;
}

//bottom
for(int j=n-offset; j>start; j--) {
    matrix[n-offset][j] = num++;
}

//left
for(int i=n-offset; i>start; i--) {
    matrix[i][start] = num++;
}
offset++;
start++;

代码随想录是这么写的:

for (j = start; j < n - loop; j++) {
	res[start][j] = count++;
}

// 模拟右侧从上到下
for (i = start; i < n - loop; i++) {
    res[i][j] = count++;
}

// 模拟下侧从右到左
for (; j >= loop; j--) {
    res[i][j] = count++;
}

// 模拟左侧从下到上
for (; i >= loop; i--) {
    res[i][j] = count++;
}
start++;

巧妙的点

① 合并了 loop 和 offset 两个变量。
② i 和 j 可以连贯使用。
第一个for (处理上侧从左到右)执行后,j++,此时 j 为 n-offset, 然后跳出循环,这个 j 是可以复用的。因为紧接着第二个 for(处理右侧从上到下),其中的 纵坐标,也就是 j 是不变的。

我提交的代码

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] matrix = new int[n][n];
        int loop = n/2;
        int start = 0 ;
        int offset = 1;
        int num=1;
         while(--loop >= 0) {
            //top
            for(int j=start; j<n-offset; j++) {
                matrix[start][j] = num++;
            }

            //right
            for(int i=start; i<n-offset; i++) {
                matrix[i][n-offset] = num++;
            }

            //bottom
            for(int j=n-offset; j>start; j--) {
                matrix[n-offset][j] = num++;
            }

            //left
            for(int i=n-offset; i>start; i--) {
                matrix[i][start] = num++;
            }
            offset++;
            start++;
        }
       if(n % 2 != 0) {
            matrix[n/2][n/2] = num++;
        }
        return matrix;
    }
}

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值