每日打卡:螺旋矩阵

391 阅读2分钟

这是我参与2022首次更文挑战的第15天,活动详情查看:2022首次更文挑战

给你一个 mn 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

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

原题链接

我刚看到这道题的时候我们就不知道从哪下手,之后我就看这个图,这道题总体上就分为四部分,从左到右,从右到下,从下到左,从左到上,给了我们一个二维数组,那我们就可以根据我们的角标循环就可以了。

因为我们是不断地向内缩进,我们就需要确定他四个角的位置,来约束它向内循环,有了这些条件之后,我写出了我的第一版代码

public static List<Integer> spiralOrder(int[][] matrix) {

        List<Integer> result = new ArrayList<Integer>();
        if(matrix==null||matrix.length == 0||matrix[0].length == 0){
            return result;
        }
        int top=0;
        int left=0;
        int right=matrix[0].length - 1;
        int bottom=matrix.length-1;

        while (top <= bottom && left <= right){
            //左到右
            for (int i = left; i <=right; i++){
                result.add(matrix[top][i]);
                
            }
            //上到下
            //这里top+1是因为上一个循环我们就已经得到top位置的数,
            for (int j = top+1; j<=bottom; j++){
                result.add(matrix[j][right]);               
            }
            //右到左
            //原因如上
            for (int x = right-1; x>left; x--){
                result.add(matrix[bottom][x]);                
            }
            //下到上
            for (int y = bottom; y >top;y--){
                result.add(matrix[y][left]);
            }
            left++;
            right--;
            top++;
            bottom--;
        }
        return result;

这一版代码它跑过了我们的测试用例,提交的时候出现了问题,就是在我们遇到只有一条数据的时候我们左右和上下会出现重复的问题,所以我添加了两个判断

        if(matrix[0].length==1){
            for (int i = 0; i <matrix.length; i++){
                result.add(matrix[i][0]);
                System.out.println(matrix[i][0]);
            }
            return result;
        }
        if(matrix.length==1){
            for (int i = 0; i < matrix[0].length; i++){
                result.add(matrix[0][i]);
                System.out.println(matrix[0][i]);
            }
            return result;
        }

添加判断之后又出现问题,{{1,2,3},{4,5,6},{7,8,9},{10,11,12}}的例子出现最后重复,还是我们刚刚·1的问题没有得到解决

那么我们刚刚这个问题的本质是什么,就是我们直上直下的,我们没有做判断,那我们四周的操作是对称的,那我把他的逆操作加上判断

     public static List<Integer> spiralOrder(int[][] matrix) {

       List<Integer> result = new ArrayList<Integer>();
        if(matrix==null||matrix.length == 0||matrix[0].length == 0){
            return result;
        }
        int top=0;
        int left=0;
        int right=matrix[0].length - 1;
        int bottom=matrix.length-1;
        
        while (top <= bottom && left <= right){
            for (int i = left; i <=right; i++){
                result.add(matrix[top][i]);
                System.out.println(matrix[top][i]);
            }
            for (int j = top+1; j<=bottom; j++){
                result.add(matrix[j][right]);
                System.out.println(matrix[j][right]);
            }
            //判断我们的往复操作
            if(left<right&&top < bottom){
                for (int x = right-1; x>left; x--){
                    result.add(matrix[bottom][x]);
                    System.out.println(matrix[bottom][x]);
                }
                for (int y = bottom; y >top;y--){
                    result.add(matrix[y][left]);
                    System.out.println(matrix[y][left]);
                }  
            }
            
            left++;
            right--;
            top++;
            bottom--;
        }
        return result;
    }

我在做这道题的时候想了一会思路出现的很快,但是小问题很多,尤其是边界问题,我把我的代码放到了编译器当中,debug不断的调试,来确定我的边界,之后遇到特殊的用例使用if去做判断,其实我们我们做好多提的时候,有一些特殊用例的确我们可以使用单独的判断来解决的我们的问题,但是多数之后还是会出问题,我们应该去看一看我们逻辑的问题是怎么样的。