leecoode54螺旋矩阵——带有调试代码

该文章讨论了一段Java代码,用于按螺旋顺序遍历二维矩阵。作者指出了在处理循环边界和中间数据时可能出现的问题,并分享了从他人题解中学习到的解决方案。经过优化,代码去除了不必要的变量,简化了逻辑,能够正确处理不同尺寸的矩阵。
摘要由CSDN通过智能技术生成

我参考的别人的题解

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> ans = new ArrayList<Integer>();
        int m = matrix[0].length;
        int n = matrix.length;
        int i,j;
        int startx = 0;
        int starty = 0;
        int loop = Math.min(m,n)/2; 
        int mid = Math.min(m,n)/2;
        int offset = 1;
        while (loop > 0) {
            i = startx;
            j = starty;
            for (j = starty; j < starty + m - offset; j++) {
                ans.add(matrix[startx][j]);
            }
     
            for (i = startx; i < startx + n - offset; i++) {
                ans.add(matrix[i][j]);
            }
          
            for (; j > starty; j--) {
                ans.add(matrix[i][j]);
            }
         
            for (; i > startx; i--) {
                ans.add(matrix[i][j]);
            }
            startx++;
            starty++;
            loop--;
            offset += 2;
        }
        if ((Math.min(m,n)%2) != 0 ) {
            if(m > n){
                for ( j = mid; j < mid + m - n + 1; ++j) {
                    ans.add(matrix[mid][j]);
                }
            }
            else {
                for ( i = mid; i < mid + n - m + 1; ++i) {
                    ans.add(matrix[i][mid]);
                }
            }
        }
        return ans;
    }
}

我的题解

自我解释

这个代码的题解
螺旋矩阵中最容易搞错的就是这个循环的边界问题,正如这个carl师兄说的,一入循环深似海,这个边界问题总是能够造成各种各样的问题和麻烦
我在这个题循环边界遇到的问题比较少,但是我对于这个外层循环circle的范围产生了错解
因为我刚开始拿3 5 4 5等举例子,我下意思的认为这个循环的次数只与行数有关,而与列数无关,所以我这个循环的次数是错误的,它只能够解决一半的问题,当遇到 5 3这种,循环就不适用了,于是我查看别人的正确代码,我才发现原来循环并不只与行数有关,还要与列数有关。
第二个问题就是如何正确处理中间数据的问题,我只处理了横着的数据,但是竖着的数据却不会处理,又是只弄出来一半,因为我并没有意思到这个横竖的特殊情况的出现是与m和n的大小相关的,我以为所有的特殊情况都是横着的,也就是前面提到,我并没有考虑到5还3 的情况
考虑到上面两个问题之后,这个题就很容易进行解答了
对参考题解的优化,我在看参考题解的时候我就有一个很不明白的店,为什么要引入这个offset变量和startx和starty变量,感觉这个确实是没必要的,尤其是让offset加2,然后startx和starty加1的操作我很迷惑,觉得这个空间完全可以省下来。我们就可以通过这个circle的值来调整这个循环的次数。

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> integerList = new ArrayList<>();
        int circle=0;
        int i=0,j=0;
        int m = matrix.length;
        int n = matrix[i].length;
        int mid = Math.min(m,n)/2;
        while(circle<mid){
            //这个的遍历是以n为圈的
            for(i=circle,j=circle;j<n-1-circle;j++){
                integerList.add(matrix[i][j]);
            }
            //前面加两个判断条件
            for(i=circle;i<m-1-circle;i++){
                integerList.add(matrix[i][j]);
            }
            for(j=n-1-circle;j>circle;j--){
                integerList.add(matrix[i][j]);
            }
            for(i=m-circle-1;i>circle;i--){
                integerList.add(matrix[i][j]);
            }
            circle++;//圈数加一
        }

        if(Math.min(m,n)%2!=0)
        {
            if(n>m){
                for(j=mid;j<mid+n-m+1;j++){
                    integerList.add(matrix[mid][j]);
                }
            }else {
                for(i=mid;i<mid+m-n+1;i++){
                    integerList.add(matrix[i][mid]);
                }
            }
        }
        return integerList;
    }
}

完整代码-带有测试代码可以在这里调试

package demo.day2;

import java.util.ArrayList;
import java.util.List;
//import java.util.ArrayList;
import java.util.Scanner;

public class 螺旋矩阵54 {
    public static void main(String[] args) {
        int m,n;
        Scanner input = new Scanner(System.in);
        System.out.println("请输入m和n");
        m=input.nextInt();
        n=input.nextInt();
        int[][] arr = new int[m][n];
        for (int i = 0; i < m; i++) {
            for(int j=0;j<n;j++){
                arr[i][j]=input.nextInt();
            }
        }
        List<Integer> integerList = spiralOrder(arr);
        for (int item : integerList) {
            System.out.print(item+"  ");
        }
        input.close();
    }

    public static List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> integerList = new ArrayList<>();
        int circle=0;
        int i=0,j=0;
        int m = matrix.length;
        int n = matrix[i].length;
        int mid = Math.min(m,n)/2;
        while(circle<mid){
            //这个的遍历是以n为圈的
            for(i=circle,j=circle;j<n-1-circle;j++){
                integerList.add(matrix[i][j]);
            }
            //前面加两个判断条件
            for(i=circle;i<m-1-circle;i++){
                integerList.add(matrix[i][j]);
            }
            for(j=n-1-circle;j>circle;j--){
                integerList.add(matrix[i][j]);
            }
            for(i=m-circle-1;i>circle;i--){
                integerList.add(matrix[i][j]);
            }
            circle++;//圈数加一
        }

        if(Math.min(m,n)%2!=0)
        {
            if(n>m){
                for(j=mid;j<mid+n-m+1;j++){
                    integerList.add(matrix[mid][j]);
                }
            }else {
                for(i=mid;i<mid+m-n+1;i++){
                    integerList.add(matrix[i][mid]);
                }
            }
        }
        return integerList;
        
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值