每日一练(17):顺时针打印矩阵

简介: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。


示例 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]


限制:


0 <= matrix.length <= 100

0 <= matrix[i].length <= 100


来源:力扣(LeetCode)


链接:https://leetcode-cn.com/probl...


方法:设定边界


根据题目示例 matrix = [[1,2,3],[4,5,6],[7,8,9]] 的对应输出 [1,2,3,6,9,8,7,4,5] 可以发现,顺时针打印矩阵的顺序是 “从左向右、从上向下、从右向左、从下向上” 循环。


因此,考虑设定矩阵的“左、上、右、下”四个边界,模拟以上矩阵遍历顺序。


算法流程:


1.空值处理: 当 matrix 为空时,直接返回空列表 [] 即可。

2.初始化: 矩阵 左、右、上、下 四个边界 l , r , t , b ,用于打印的结果列表 res 。

3.循环打印: “从左向右、从上向下、从右向左、从下向上” 四个方向循环,每个方向


打印中做以下三件事 (各方向的具体信息见下表) ;


  • 1.根据边界打印,即将元素按顺序添加至列表 res 尾部;
  • 2.边界向内收缩 11 (代表已被打印);
  • 3.判断是否打印完毕(边界是否相遇),若打印完毕则跳出。
  • 4.返回值: 返回 res 即可。


打印方向 1. 根据边界打印 2. 边界向内收缩 3. 是否打印完毕
从左向右 左边界 l ,右边界 r 上边界 t 加 1 是否 t > b
从上向下 上边界 t ,下边界 b 右边界 r 减 1 是否 l > r
从右向左 右边界 r ,左边界 l 下边界 b 减 1 是否 t > b
从下向上 下边界 b ,上边界 t 左边界 l 加 1 是否 l > r


复杂度分析:


  • 时间复杂度 O(MN) : M,N 分别为矩阵行数和列数。
  • 空间复杂度 O(1) : 四个边界 l , r , t , b 使用常数大小的 额外 空间( res 为必须使用的空间)。


vector<int> spiralOrder(vector<vector<int>>& matrix) {
    if (matrix.empty()) {
        return {};
    }
    vector<int> res;
    int l = 0;                      //左边界
    int r = matrix[0].size() - 1;   //右边界
    int t = 0;                      //上边界
    int b = matrix.size() - 1;      //下边界
    while (true) {
        //left -> right
        for (int i = l; i <= r; i++) {
            res.push_back(matrix[t][i]);
        }
        if (++t > b) {
            break;
        }
        //top -> bottom
        for (int i = t; i <= b; i++) {
            res.push_back(matrix[i][r]);
        }
        if (--r < l) {
            break;
        }
        //right -> left
        for (int i = r; i >= l; i--) {
            res.push_back(matrix[b][i]);
        }
        if (--b < t) {
            break;
        }
        //bottom -> top
        for (int i = b; i >= t; i--) {
            res.push_back(matrix[i][l]);
        }
        if (++l > r) {
            break;
        }
    }
    return res;
}


目录
相关文章
|
移动开发 Dart 前端开发
AliFlutter - 面向阿里集团的Flutter体系化建设
阿里巴巴集团移动技术委员会联合淘系技术部重磅推出「AliFlutter系列直播」,文中可以报名哦!
7609 0
AliFlutter - 面向阿里集团的Flutter体系化建设
|
6月前
|
机器学习/深度学习
位置编码详解
位置编码为Transformer提供序列位置信息,弥补注意力机制无位置感知的缺陷。主要分绝对(如可学习、Sinusoidal)和相对(如RoPE、ALiBi)两类。RoPE通过旋转矩阵支持长序列,ALiBi以线性偏置增强外推能力。不同方法在长度外推、效率上各有优劣,广泛应用于LLaMA、BLOOM等大模型,是面试考察重点。
|
11月前
|
算法 安全 Java
java中Collections.shuffle方法的功能说明
`Collections.shuffle()` 是 Java 中用于随机打乱列表顺序的方法,基于 Fisher-Yates 算法实现,常用于洗牌、抽奖等场景。可选 `Random` 参数支持固定种子以实现可重复的随机顺序。方法直接修改原列表,无返回值。
354 0
|
自然语言处理 API C++
阿里通义推出SmartVscode插件,自然语言控制VS Code,轻松开发应用,核心技术开源!
SmartVscode插件深度解析:自然语言控制VS Code的革命性工具及其开源框架App-Controller
2618 1
阿里通义推出SmartVscode插件,自然语言控制VS Code,轻松开发应用,核心技术开源!
|
6月前
|
监控 网络安全 iOS开发
|
7月前
|
机器学习/深度学习 人工智能 供应链
从“识图”到“购得”:图片搜索商品如何重构消费与供应链逻辑?
图片搜索正重塑电商:从“看到”到“买到”,只需一张图。它以AI解析视觉特征,精准匹配商品,打通C端购物与B端供应链,让找货、比价、溯源高效直达,成为连接视觉信息与交易的核心纽带。
|
前端开发 安全 JavaScript
Python的Flask框架的学习笔记(前后端变量传送,文件上传,网页返回)内含实战:实现一个简单的登录页面
Python的Flask框架的学习笔记(前后端变量传送,文件上传,网页返回)内含实战:实现一个简单的登录页面
774 0
|
Go
Golang语言结构体(struct)面向对象编程基础篇
这篇文章是关于Go语言中结构体(struct)面向对象编程的基础教程,详细介绍了面向对象编程在Go语言中的应用、结构体的定义与初始化、方法定义、跨包实例化结构体以及结构体方法和普通函数的区别。
352 4
|
SQL 数据采集 运维
蚂蚁第三代混沌工程助力风险防控提升
蚂蚁第三代混沌工程助力风险防控提升
3636 1
蚂蚁第三代混沌工程助力风险防控提升