LeetCode第54题

难度:中等

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

示例1:

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

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

示例2:

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

输出:[1,2,3,4,8,12,11,10,9,5,6,7]

  • m == matrix.length

  • n == matrix[i].length

  • 1 <= m, n <= 10

  • -100 <= matrix[i][j] <= 100

问题分析

这题是让顺时针螺旋顺序返回矩阵中的所有元素,我们可以直接模拟,从外到内一圈一圈的打印矩阵中的元素,需要使用4个变量来记录访问的位置,直到全部元素都访问完为止,如下图所示。

这里还要注意上下左右四个方向访问的边界,哪些是开区间哪些是闭区间,代码如下。

JAVA:

复制代码
public List<Integer> spiralOrder(int[][] matrix) {
    List<Integer> ans = new ArrayList<>();
    int n = matrix.length, m = matrix[0].length;
    int up = 0, down = n - 1, left = 0, right = m - 1;
    int total = m * n;// 总的元素个数
    while (ans.size() < total) {
        // 上面,从左往右打印,左闭右闭区间[left,right]
        for (int i = left; i <= right && ans.size() < total; i++)
            ans.add(matrix[up][i]);
        // 右边,从上往下打印,上开下开区间(up,down)
        for (int i = up + 1; i <= down - 1 && ans.size() < total; i++)
            ans.add(matrix[i][right]);
        // 下边,从右往左打印,右闭左闭区间[right,left]
        for (int i = right; i >= left && ans.size() < total; i--)
            ans.add(matrix[down][i]);
        // 左边,从下往上打印,下开上开区间(down,up)
        for (int i = down - 1; i >= up + 1 && ans.size() < total; i--)
            ans.add(matrix[i][left]);
        left++;
        right--;
        up++;
        down--;
    }
    return ans;
}

C++:

复制代码
public:
    vector<int> spiralOrder(vector<vector<int>> &matrix) {
        vector<int> ans;
        int n = matrix.size(), m = matrix[0].size();
        int up = 0, down = n - 1, left = 0, right = m - 1;
        int total = m * n;// 总的元素个数
        while (ans.size() < total) {
            // 上面,从左往右打印,左闭右闭区间[left,right]
            for (int i = left; i <= right && ans.size() < total; i++)
                ans.push_back(matrix[up][i]);
            // 右边,从上往下打印,上开下开区间(up,down)
            for (int i = up + 1; i <= down - 1 && ans.size() < total; i++)
                ans.push_back(matrix[i][right]);
            // 下边,从右往左打印,右闭左闭区间[right,left]
            for (int i = right; i >= left && ans.size() < total; i--)
                ans.push_back(matrix[down][i]);
            // 左边,从下往上打印,下开上开区间(down,up)
            for (int i = down - 1; i >= up + 1 && ans.size() < total; i--)
                ans.push_back(matrix[i][left]);
            left++;
            right--;
            up++;
            down--;
        }
        return ans;
    }

Python:

复制代码
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
    ans = []
    n, m = len(matrix), len(matrix[0])
    up, down, left, right = 0, n - 1, 0, m - 1
    total = m * n  # 总的元素个数
    while len(ans) < total:
        # 上面,从左往右打印,左闭右闭区间[left,right]
        for i in range(left, right + 1):
            ans.append(matrix[up][i])
        # 右边,从上往下打印,上开下闭区间(up,down]
        for i in range(up + 1, down + 1):
            ans.append(matrix[i][right])
        # 上下重叠就终止
        if up == down or left == right: break
        # 下边,从右往左打印,右开左闭区间(right,left]
        for i in range(right - 1, left - 1, -1):
            ans.append(matrix[down][i])
        # 左边,从下往上打印,下开上开区间(down,up)
        for i in range(down - 1, up, -1):
            ans.append(matrix[i][left])
        left += 1
        right -= 1
        up += 1
        down -= 1
    return ans
相关推荐
俩娃妈教编程2 小时前
2025 年 06 月 三级真题(1)--分糖果
c++·算法·gesp真题
tankeven2 小时前
HJ97 记负均正
c++·算法
俩娃妈教编程2 小时前
2025 年 06 月 三级真题(2)--奇偶校验
c++·算法·gesp真题
Flying pigs~~2 小时前
机器学习之线性回归
人工智能·算法·机器学习·数据挖掘·回归·线性回归
LCG元2 小时前
电机控制进阶:STM32F303硬件比较器实现FOC算法解析
stm32·嵌入式硬件·算法
丰海洋2 小时前
Leetcode-hot100-136只出现一次的数字
算法·leetcode·职场和发展
We་ct2 小时前
LeetCode 124. 二叉树中的最大路径和:刷题解析
前端·数据结构·算法·leetcode·typescript
Anastasiozzzz4 小时前
MySQL JOIN:底层原理、算法演进与多表性能之谜
算法
追随者永远是胜利者10 小时前
(LeetCode-Hot100)253. 会议室 II
java·算法·leetcode·go