IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【LeetCode】剑指 Offer 29. 顺时针打印矩阵 -> 正文阅读

[数据结构与算法]【LeetCode】剑指 Offer 29. 顺时针打印矩阵

【LeetCode】剑指 Offer 29. 顺时针打印矩阵

在这里插入图片描述

一、设定边界

根据题目示例可以发现,顺时针打印矩阵的顺序是”从左向右,从上向下、从右向左、从下向上“循环

因此,考虑设定矩阵的”左、上、右、下“四个边界,模拟以上矩阵遍历顺序
在这里插入图片描述

算法流程:

  • 空值处理:当 matrix 为空时,直接返回列表 [] 即可
  • 初始化:矩阵左右上下四个边界 l、r、t、b,用于打印的结果列表 res
  • 循环打印:”从左向右、从上向下、从右向左、从下向上“四个方向循环,每个方向打印中做以下三件事(各方向的具体信息见下表);
    1. 根据边界打印,也就是将元素按顺序添加至列表 res 尾部
    2. 边界向内收缩 1 (代表已被打印)
    3. 判断是否打印完毕(边界是否相遇),若打印完毕则跳出
  • 返回值:返回 res 即可
    在这里插入图片描述
class Solution {
    public int[] spiralOrder(int[][] matrix) {
        if(matrix.length == 0) return new int[0];
		int l = 0;
		int r = matrix[0].length - 1;
		int t = 0;
		int b = matrix.length - 1;
		int x = 0;
		int[] arr = new int[(r+1)*(b+1)];
        while(true) {
            for(int i = l; i <= r; i++) arr[x++] = matrix[t][i];
            if(++t > b) break;
            for(int i = t; i <= b; i++) arr[x++] = matrix[i][r];
            if(--r < l) break;
            for(int i = r; i >= l; i--) arr[x++] = matrix[b][i];
            if(--b < t) break;
            for(int i = b; i >= t; i--) arr[x++] = matrix[i][l];
            if(++l > r) break;
        }
        return arr;
    }
}			
  • 时间复杂度 O(m*n):M,N 分别为矩阵行数和列数
  • 空间复杂度 P(1):四个边界 l、r、t、b 使用常数大小的额外空间(res 为必须使用的空间)

二、按层模拟

可以将矩阵看成若干层,首先打印最外层的元素,其次打印次外层的元素,直到打印最内层的元素

定义矩阵的第 k 层是到最近边界距离为 k 的所有顶点。例如,下图矩阵最外层元素都是第 1 层,次外层元素都是第 2 层,剩下的元素都是第 3 层

[[1, 1, 1, 1, 1, 1, 1],
[1, 2, 2, 2, 2, 2, 1],
[1, 2, 3, 3, 3, 2, 1],
[1, 2, 2, 2, 2, 2, 1],
[1, 1, 1, 1, 1, 1, 1]]

对于每层,从左上方开始以顺时针的顺序遍历所有元素。假设当前层的左上角位于(top,left),右下角位于(bottom,right),按照如下顺序遍历当前层的元素

  • 从左到右遍历上侧元素,依次为(top,left)到(top,right)
  • 从上到下遍历右侧元素,依次为(top+1,right)到(bottom,right)
  • 如果 left < right 且 top < bottom,则从右到左遍历下侧元素,依次为(bottom,right - 1)到(bottom,left + 1),以及从上到下遍历左侧元素,依次为(bottom,left)到(top + 1,left)

遍历完当前层的元素之后,将 left 和 top 分别增加 1,将 right 和 bottom 分别减少 1,进入下一层继续遍历,直到遍历完所有元素为止
在这里插入图片描述

class Solution {
    public int[] spiralOrder(int[][] matrix) {
        if(matrix.length == 0) return new int[0];
        int rows = matrix.length;
        int columns = matrix[0].length;
        int[] arr = new int[columns * rows];
        int l = 0;
        int t = 0;
        int r = columns - 1;
        int b = rows - 1;
        int x = 0;
        while(l <= r && t <= b){
            for(int i = l; i <= r; i++){
                arr[x++] = matrix[t][i]; 
            }
            for(int i = t+1; i <= b; i++){
                arr[x++] = matrix[i][r];
            }
            //如果 l = r,或者 t = b,那就不需要执行下面了,只需要进行下一次 while 循环就能遍历完
            if(l < r && t < b){
                for(int i = r - 1; i > l; i--){
                    arr[x++] = matrix[b][i];
                }
                for(int i = b; i > t; i--){
                    arr[x++] = matrix[i][l];
                }
            }
            l++;
            t++;
            r--;
            b--;
        }
        return arr;
    }
}
  • 时间复杂度:O(m * n),其中 m 和 n 分别是输入矩阵的行数和列数。矩阵中的每个元素都要被访问一次
  • 空间复杂度:O(1),除了输出数组外,空间复杂度是常数

总结

这一题让我联想到了【Java 数据结构与算法】第五章的迷宫回溯,也是模拟矩阵周围有边界,也是一直遍历碰到边界就找别的路线,到最后我都已经改出来了,却发现思路不对。我的思路是从矩阵左上角开始,先看右边能不能走,不能走就看下边,又不能走就看左边,左边还不能走就看上边,直到最后哪都不能走就说明遍历完了。这样的一直遍历到左下角是都没有问题的,往后就有问题了,左下角走过了,发现左右下都不能走,然后向上走。这个时候按照题意应该继续向上的,可是我的算法是先看右边能不能走,这个时候右边肯定是能走的,因此就往右走了,这样就不符合题意了。官方题解给了两个解法,虽然第二个解法在下面,但是第二个解法不如第一个巧妙简便
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-04 11:27:49  更:2021-08-04 11:28:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 18:47:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码