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
相关推荐
CoderCodingNo6 小时前
【NOIP】2011真题解析 luogu-P1003 铺地毯 | GESP三、四级以上可练习
算法
iFlyCai6 小时前
C语言中的指针
c语言·数据结构·算法
查古穆7 小时前
栈-有效的括号
java·数据结构·算法
再一次等风来7 小时前
近场声全息(NAH)仿真实现:从阵列实值信号到波数域重建
算法·matlab·信号处理·近场声全息·nah
汀、人工智能7 小时前
16 - 高级特性
数据结构·算法·数据库架构·图论·16 - 高级特性
大熊背7 小时前
利用ISP离线模式进行分块LSC校正的方法
人工智能·算法·机器学习
XWalnut7 小时前
LeetCode刷题 day4
算法·leetcode·职场和发展
蒸汽求职7 小时前
机器人软件工程(Robotics SDE):特斯拉Optimus落地引发的嵌入式C++与感知算法人才抢夺战
大数据·c++·算法·职场和发展·机器人·求职招聘·ai-native
AI成长日志8 小时前
【笔面试算法学习专栏】双指针专题·简单难度两题精讲:167.两数之和II、283.移动零
学习·算法·面试
旖-旎8 小时前
分治(库存管理|||)(4)
c++·算法·leetcode·排序算法·快速选择算法