day13【LeetCode力扣】54.螺旋矩阵

day13【LeetCode力扣】54.螺旋矩阵

1.题目描述

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

示例 1:

img

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

示例 2:

img

输入: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

2.题解

就是模拟遍历,首先要弄清的就是循环不变量,这里是建议进行左闭右开很容易理解,代码附上,注释加好大家自行理解,多看几遍便能想明白,手动模拟一下。

c++

class Solution {
public:
    // 定义一个名为 spiralOrder 的函数,参数为一个二维 vector,返回一个一维 vector
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        // 获取传入矩阵的行数和列数
        int m=matrix.size();
        int n=matrix[0].size();
        // 如果矩阵为空,则返回空 vector
        if(m==0||n==0)
            return {};
        // 定义一个长度为 m*n 的一维 vector,用于存储螺旋遍历结果
        vector<int> res(m*n);
        // 定义 loop 为行数和列数中较小的那个值除以2(向下取整),为总遍历轮次
        int loop=min(m,n)/2;
        // 定义 mid 为 loop 的值,表示遍历的起始位置
        int mid=loop;
        // 定义 startx 和 starty 分别为当前遍历的起始行和起始列
        int startx=0,starty=0;
        // 定义 count 为已经遍历的元素个数,初始值为0
        int count=0;
        // 定义 offset 为当前轮次需要遍历的元素个数,初始值为1
        int offset=1;
        // 定义 i 和 j 分别为当前遍历到的行和列
        int i,j;
        // 进入循环,遍历所有轮次
        while(loop){
            // 从左到右遍历当前轮次的最上面一行
            i=startx;
            j=starty;
            for(;j<n-offset;j++){
                res[count]=matrix[i][j];
                count++;
            }
            // 从上到下遍历当前轮次的最右边一列
            for(;i<m-offset;i++){
                res[count]=matrix[i][j];
                count++;
            }
            // 从右到左遍历当前轮次的最下面一行
            for(;j>starty;j--){
                res[count]=matrix[i][j];
                count++;
            }
            // 从下到上遍历当前轮次的最左边一列
            for(;i>startx;i--){
                res[count++]=matrix[i][j];
            }
            // 更新起始行、起始列、轮次需要遍历的元素个数和已经遍历的轮次数量
            startx++;
            starty++;
            offset+=1;
            loop--;
        } 
        // 如果行数和列数中较小的那个值为奇数,则还需遍历最中间的一个元素
        if(min(m,n)%2){
            if(m>n){
                // 如果行数大于列数,则遍历中间的一列
                for(int i=mid;i<mid+m-n+1;++i)
                    res[count++]=matrix[i][mid];
            }else{
                // 如果列数大于行数,则遍历中间的一行
                for(int i=mid;i<mid+n-m+1;++i)
                    res[count++]=matrix[mid][i];
            }
        }
        // 返回螺旋遍历结果
        return res;
    }
};

python

class Solution:
    def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
        m,n = len(matrix), len(matrix[0])  # 获取矩阵的行数和列数
        loop = mid = min(m,n)//2  # 计算需要遍历的轮次,以及起始位置
        startx = starty = 0  # 起始行和起始列
        res = []  # 存储螺旋遍历结果的列表
        
        for offset in range(1, loop + 1):  # 遍历每一轮
            # 从左往右
            for i in range(starty, n - offset):
                res.append(matrix[startx][i])
            # 从上往下
            for i in range(startx, m - offset):
                res.append(matrix[i][n - offset])
            # 从右往左
            for i in range(n - offset, starty, -1):
                res.append(matrix[m - offset][i])
            # 从下往上
            for i in range(m - offset, startx, -1):
                res.append(matrix[i][starty])
            
            startx += 1  # 更新起始行和起始列
            starty += 1
        
        if min(m, n) % 2:  # 如果行数和列数中较小的那个为奇数,则还需遍历中间的元素
            if m < n:
                # 行数小于列数,遍历中间的一行
                for i in range(startx, mid + n - m + 1):
                    res.append(matrix[mid][i])
            else:
                # 列数小于行数,遍历中间的一列
                for i in range(starty, mid + m - n + 1):
                    res.append(matrix[i][mid])
        
        return res  # 返回螺旋遍历结果的列表

3.总结

数组相关题目我们暂时先练习到这里,下一章我们开始链表相关题目的学习~

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值