Middle-题目111:54. Spiral Matrix

本文介绍了一种按顺时针螺旋顺序遍历二维数组的方法,并提供了一个Java实现示例。通过定义方向变量和已访问标记数组,确保了遍历的正确性和效率。

题目原文:
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
For example,
Given the following matrix:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
You should return [1,2,3,6,9,8,7,4,5].
题目大意:
按顺时针螺旋顺序遍历二维数组。
题目分析:
Middle-题目29很像,在前面题基础上简单改一下代码即可。一个是读数组一个是写数组,所以读数组要使用一个visited[][]数组维护是否读过,而写数组只要判断是否为0即可。
源码:(language:java)

public class Solution {
    private  final int RIGHT = 1;
    private  final int DOWN = 2;
    private  final int LEFT = 3;
    private  final int UP = 4;
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> list = new ArrayList<Integer>();
        int row = matrix.length;
        if(row==0)
            return list;
        int col = matrix[0].length;
        boolean[][] visited = new boolean[row][col];
        int count = 0,direction = RIGHT,i=0,j=0;
        while (count < row * col) {
            list.add(matrix[i][j]);
            visited[i][j] = true;
            switch (direction) {
                case RIGHT:
                    if (j==col-1 || visited[i][j+1]) {
                        direction=DOWN;
                        i++;
                    }
                    else 
                        j++;
                    break;
                case DOWN:
                    if (i==row-1 || visited[i+1][j]) {
                        direction = LEFT;
                        j--;
                    }
                    else
                        i++;
                    break;
                case LEFT:
                    if (j==0 || visited[i][j-1]) {
                        direction = UP;
                        i--;
                    }
                    else
                        j--;
                    break;
                case UP:
                    if (visited[i-1][j]) {
                        direction = RIGHT;
                        j++;
                    }
                    else
                        i--;
                    break;
                default:
                    break;
            }
            count++;
        }
        return list;
    }
}

成绩:
1ms,beats 3.18%,众数1ms,71.07%

<think>题目要求:螺旋顺序遍历矩阵,返回遍历顺序的列表。 提供的代码中,变量命名有冲突,并且在更新边界时存在错误。 具体错误分析: 1. 变量命名冲突:在函数参数中,`matrix` 是一个二维列表。在内部,定义了 `row = len(matrix)` 和 `col = len(matrix[0])`。 但是在循环中,使用了 `for col in range(...)` 和 `for row in range(...)`,这会导致覆盖了前面定义的 `col` 和 `row` 变量。 在后续的循环中,`col` 和 `row` 不再是整数而变成了循环变量(整数),而在下一次循环条件判断时,`right = col - 1` 中的 `col` 已经不再是初始的列数,而是变成了上一次循环的最后一个列索引值(整数),导致逻辑错误。 2. 边界更新错误:在循环的最后,更新边界时,将 `top` 减1,`bottom` 加1,而正确的应该是 `top` 加1(因为已经遍历完顶部一行,所以顶部边界下移),`bottom` 减1(底部边界上移),同时 `left` 加1(左边界右移),`right` 减1(右边界左移)。但是代码中写的是 `top-1` 和 `bottom+1`,这样会导致边界更新错误,可能会使循环条件无法满足而提前退出,或者多遍历。 3. 循环条件:在循环中,当最内层环时,如果只有一行或一列,那么内层的两个循环(向左和向上)就不应该执行。代码中使用了 `if left < right and top < bottom:` 来避免重复,这是正确的。但是,由于变量覆盖和边界更新错误,这个条件可能无法正确判断。 修正方案: 1. 避免变量覆盖:将循环变量改为不同的名字,例如使用 `i` 和 `j` 或者 `c` 和 `r`。 2. 修正边界更新:将 `top` 更新为 `top+1`,`bottom` 更新为 `bottom-1`。 修正后的代码: ```python class Solution: def spiralOrder(self, matrix: List[List[int]]) -> List[int]: if not matrix or not matrix[0]: return [] m = len(matrix) n = len(matrix[0]) result = [] left, right, top, bottom = 0, n - 1, 0, m - 1 while left <= right and top <= bottom: # 从左到右遍历上边 for j in range(left, right + 1): result.append(matrix[top][j]) # 从上到下遍历右边 for i in range(top + 1, bottom + 1): result.append(matrix[i][right]) # 如果还有内层(不止一行且不止一列),则遍历底边和左边 if left < right and top < bottom: # 从右到左遍历底边(注意:从right-1到left+1,所以右开左开,步长-1) for j in range(right - 1, left, -1): result.append(matrix[bottom][j]) # 从下到上遍历左边(注意:从bottom到top+1,所以从下往上,到top+1停止,不包含top) for i in range(bottom, top, -1): result.append(matrix[i][left]) # 更新边界:向内收缩 left, right, top, bottom = left + 1, right - 1, top + 1, bottom - 1 return result ``` 注意:在内部两个反向循环中,我们确保只在有多行多列的情况下才执行。同时,循环变量改为 `i` 和 `j`,避免覆盖。 现在,边界更新正确:每一轮循环后,上边界下移(top+1),下边界上移(bottom-1),左边界右移(left+1),右边界左移(right-1)。 这样,代码应该可以正确运行。 §§相关问题§§ 1. 在螺旋遍历矩阵时,如何处理空矩阵或只有一行/一列的特殊情况? 2. 为什么在内部两个反向循环中需要判断 `if left < right and top < bottom`? 3. 如果要求逆时针螺旋遍历矩阵,应如何修改上述代码? 4. 螺旋遍历算法的时间复杂度和空间复杂度分别是多少?</think>您的代码实现了矩阵的螺旋顺序遍历,但存在两个关键错误: 1. **变量命名冲突**: - 初始定义了 `row = len(matrix)` 和 `col = len(matrix[0])` - 但在循环中重复使用 `col` 和 `row` 作为循环变量: ```python for col in range(left, right + 1): # 覆盖了初始的col变量 for row in range(top + 1, bottom + 1): # 覆盖了初始的row变量 ``` - 导致后续 `col` 和 `row` 不再是矩阵维度,而是变成了整数循环值 2. **边界更新错误**: ```python left, right, top, bottom = left+1, right-1, top-1, bottom+1 ``` - 正确的更新方向: - `top` 应 **增加**(上边界下移) - `bottom` 应 **减少**(下边界上移) - 但代码中: - `top-1` 使上边界上移(错误) - `bottom+1` 使下边界下移(错误) ### 修正后的代码: ```python class Solution: def spiralOrder(self, matrix: List[List[int]]) -> List[int]: if not matrix or not matrix[0]: return [] m = len(matrix) n = len(matrix[0]) # 使用m,n避免命名冲突 result = [] left, right, top, bottom = 0, n - 1, 0, m - 1 while left <= right and top <= bottom: # 遍历上边 (左->右) for j in range(left, right + 1): # 改用j作为循环变量 result.append(matrix[top][j]) # 遍历右边 (上->下) for i in range(top + 1, bottom + 1): # 改用i作为循环变量 result.append(matrix[i][right]) # 确保存在内层 if left < right and top < bottom: # 遍历底边 (右->左) for j in range(right - 1, left, -1): result.append(matrix[bottom][j]) # 遍历左边 (下->上) for i in range(bottom, top, -1): result.append(matrix[i][left]) # 正确边界收缩 left, right, top, bottom = left + 1, right - 1, top + 1, bottom - 1 return result ``` ### 关键修正: 1. 将维度变量重命名为 `m` 和 `n` 避免冲突 2. 循环变量改用 `i` 和 `j` 3. 边界更新修正为: - `top + 1`(上边界下移) - `bottom - 1`(下边界上移) - `left + 1`(左边界右移) - `right - 1`(右边界左移)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值