数据结构学习 jz29 顺时针打印矩阵

关键词:模拟

题目:螺旋遍历二维数组

简单题做了超过40分钟 调了很久 不好 

方法一:

我自己做的。

思路:

xy_t:

记录xy的方向,往右走,往下走,往左走,往上走

t控制方向

std::vector<std::vector<int>>xy_t{ {0,1},{1,0},{0,-1},{-1,0} };

isx:

        true:轮到x方向动

        false:轮到y方向动

bool isx = false;

n_res m_res:

        n_res:还没走过的行数(x方向)

        m_res:还没走过的列数(y方向)

int n_res = n, m_res = m;

res:

        现在走的方向剩余的行数/列数。

int res = isx ? n_res : m_res;

step:

        现在走的这一行/这一列已经走过的步数。

记录结果,步数加一:

result.push_back(array[x][y]);
step++;

如果step+1超过res,意味着这一行/这一列走到底了:

        1、如果isx==true(在x方向上走了一列),那么m_res-1 

        2、如果isx==false(在y方向上走了一行),那么n_res-1 

        3、isx方向反转

        4、改变t控制的方向

        5、step归零

            if (step + 1 > res)
            {
                n_res = isx ? n_res : n_res - 1;
                m_res = !isx ? m_res : m_res - 1;
                isx = !isx;
                t = (t + 1) % 4;
                step = 0;
            }

走下一步:

            x = x + xy_t[t][0];
            y = y + xy_t[t][1];

 比如:

先沿y方向走一行。

走完之后,n_res--

再沿x方向走一列。

走完之后,m_res--

循环这个过程直到所有数被走完。

复杂度计算:

时间复杂度O(nm)

空间复杂度O(1)

代码:

class Solution {
public:
    std::vector<int> spiralArray(std::vector<std::vector<int>>& array) {
        std::vector<int> result;
        if (array.empty() || array[0].empty()) return result;
        int n = array.size(), m = array[0].size();
        int x = 0, y = 0;
        std::vector<std::vector<int>>xy_t{ {0,1},{1,0},{0,-1},{-1,0} };
        bool isx = false;
        int n_res = n, m_res = m;
        int step = 0;
        int t = 0;
        for (int i = 0; i < n * m; i++)
        {
            int res = isx ? n_res : m_res;
            result.push_back(array[x][y]);
            step++;
            if (step + 1 > res)
            {
                n_res = isx ? n_res : n_res - 1;
                m_res = !isx ? m_res : m_res - 1;
                isx = !isx;
                t = (t + 1) % 4;
                step = 0;
            }
            x = x + xy_t[t][0];
            y = y + xy_t[t][1];
        }
        return result;
    }
};

方法二:

看了k神的提示,弄了四面会活动的墙。显然比我原本的好。

思路:

四面墙:

        l左墙

        r右墙

        t上墙

        b下墙

int l = 0, r = m - 1, t = 0, b = n - 1;

cut:

        统计已经走过的格子的个数。

从左往右走:

碰到右墙就停止。

走完之后上面第一行已经走完,上墙往下移动一行,t++。

            for (int i = l; i <= r; ++i)
            {
                cut++;
                result.push_back(array[t][i]);
            }
            if (cut >= m * n) break;
            t++;

从上往下走:

碰到下墙就停止。

走完之后右边第一列已经走完,右墙往左移动一列,r--。

            for (int i = t; i <= b; ++i)
            {
                cut++;
                result.push_back(array[i][r]);
            }
            if (cut >= m * n) break;
            r--;

从右往左走:

碰到左墙就停止。

走完之后下面第一行已经走完,下墙往上移动一行,b--。

            for (int i = r; i >= l; --i)
            {
                cut++;
                result.push_back(array[b][i]);
            }
            if (cut >= m * n) break;
            b--;

从下往上走:

碰到上墙就停止。

走完之后左边第一列已经走完,左墙往右移动一列,l++。

            for (int i = b; i >= t; --i)
            {
                cut++;
                result.push_back(array[i][l]);
            }
            if (cut >= m * n) break;
            l++;

复杂度计算:

时间复杂度O(nm)

空间复杂度O(1)

代码:

class Solution {
public:
    std::vector<int> spiralArray(std::vector<std::vector<int>>& array) {
        std::vector<int> result;
        if (array.empty() || array[0].empty()) return result;
        int n = array.size(), m = array[0].size();
        int l = 0, r = m - 1, t = 0, b = n - 1;
        int cut = 0;//统计已经放进result的个数
        while (true)
        {
            for (int i = l; i <= r; ++i)
            {
                cut++;
                result.push_back(array[t][i]);
            }
            if (cut >= m * n) break;
            t++;
            for (int i = t; i <= b; ++i)
            {
                cut++;
                result.push_back(array[i][r]);
            }
            if (cut >= m * n) break;
            r--;
            for (int i = r; i >= l; --i)
            {
                cut++;
                result.push_back(array[b][i]);
            }
            if (cut >= m * n) break;
            b--;
            for (int i = b; i >= t; --i)
            {
                cut++;
                result.push_back(array[i][l]);
            }
            if (cut >= m * n) break;
            l++;

        }

        return result;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/327063.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

算法第十八天-打家劫舍Ⅱ

打家劫舍Ⅱ 题目要求 解题思路 [打家劫舍Ⅱ]是说两个相邻的房间不能同时偷&#xff0c;并且首尾两个房间是相邻的&#xff08;不能同时偷首尾房间&#xff09;明显是基于[打家劫舍Ⅰ]做的升级。[打家劫舍Ⅰ]也是说两个相邻的房间不能同时偷&#xff0c;但是首尾房间不是相邻的…

Java多线程基础:虚拟线程与平台线程解析

在这篇文章中&#xff0c;主要总结一些关于线程的概念&#xff0c;以及更近期的名为虚拟线程的特性。将了解平台线程和虚拟线程在性质上的区别&#xff0c;以及它们如何促进应用程序性能的改进 经典线程背景&#xff1a; 让我们以调用外部API或某些数据库交互的场景为例&…

JVM篇--Java内存区域高频面试题

java内存区域 1 Java 堆空间及 GC&#xff1f; 首先我们要知道java堆空间的产生过程&#xff1a; 即当通过java命令启动java进程的时候&#xff0c;就会为它分配内存&#xff0c;而分配内存的一部分就会用于创建堆空间&#xff0c;而当程序中创建对象的时候 就会从堆空间来分…

918. 环形子数组的最大和

参考题解&#xff1a;https://leetcode.cn/problems/maximum-sum-circular-subarray/solutions/1152143/wo-hua-yi-bian-jiu-kan-dong-de-ti-jie-ni-892u/ class Solution {public int maxSubarraySumCircular(int[] nums) {int n nums.length;int sum nums[0], minSum nums…

【目标跟踪】跨相机如何匹配像素

文章目录 前言一、计算思路二、代码三、结果 前言 本本篇博客介绍一种非常简单粗暴的方法&#xff0c;做到跨相机像素匹配。已知各相机内外参&#xff0c;计算共视区域像素投影&#xff08;不需要计算图像特征&#xff09;。废话不多说&#xff0c;直接来&#xff0c;见下图。…

快速入门Java NIO(Not I/O)的网络通信框架--Netty

Netty 入门 了解netty前需要对nio有一定认识,该笔记基础来自bilinbili黑马,在此基础上自己学习的笔记,添加了一些自己的理解 了解java 非阻塞io编程 1. 概述 1.1 Netty 是什么&#xff1f; Netty is an asynchronous event-driven network application framework for rapid …

掌握这些测试开发技能,从容应对工作难题!

各位小伙伴, 大家好, 本期为大家分享一些测试开发工程师在企业中通过哪些测试开发技能解决难题。 一.如何定位缺陷 在企业中, 小伙伴们在发现bug后, 需要定位到具体产生bug的原因, 在这种情况下, 我们可以通过以下几种方案: 1.通过代理抓包来分析 常用的抓包工具有: Charles…

R语言【paleobioDB】——pbdb_subtaxa():统计指定类群下的子类群数量

Package paleobioDB version 0.7.0 paleobioDB 包在2020年已经停止更新&#xff0c;该包依赖PBDB v1 API。 可以选择在Index of /src/contrib/Archive/paleobioDB (r-project.org)下载安装包后&#xff0c;执行本地安装。 Usage pbdb_subtaxa (data, do.plot, col) Arguments…

Monorepo-uniapp 构建分享

Monorepo uniapp 构建灵感&#xff1a;刚好要做一个项目&#xff0c;于是想到升级一下之前自己写的一个vue3tspiniauno的模版框架&#xff0c;其实那个框架也不错&#xff1b;只是感觉还差点东西&#xff0c;我已经用那个小框架写了两三个项目&#xff1b;轻巧实用。为什么选…

CNN:Convolutional Neural Network(上)

目录 1 为什么使用 CNN 处理图像 2 CNN 的整体结构 2.1 Convolution 2.2 Colorful image 3 Convolution v.s. Fully Connected 4 Max Pooling 5 Flatten 6 CNN in Keras 原视频&#xff1a;李宏毅 2020&#xff1a;Convolutional Neural Network 1 为什么使用…

C#灵活控制多线程的状态(开始暂停继续取消)

ManualResetEvent类 ManualResetEvent是一个同步基元&#xff0c;用于在多线程环境中协调线程的执行。它提供了两种状态&#xff1a;终止状态和非终止状态。 在终止状态下&#xff0c;ManualResetEvent允许线程继续执行。而在非终止状态下&#xff0c;ManualResetEvent会阻塞线…

深度学习-标注文件处理(txt批量转换为json文件)

接上篇&#xff0c;根据脚本可将coco128的128张图片&#xff0c;按照比例划分成训练集、测试集、验证集&#xff0c;同时生成相应的标注的labels文件夹&#xff0c;最近再看实例分离比较火的mask rcnn模型&#xff0c;准备进行调试但由于实验室算力不足&#xff0c;网上自己租的…

stm32 - GPIO

stm32 - GPIO 基本结构输入输出 基本结构 所有GPIO都挂在APB2总线上 寄存器&#xff1a;内核通过APB2总线对寄存器进行读写&#xff0c;实现电平的读写 GPIO引脚的每一位对应寄存器中的某一位 GPIO中的驱动器是增加信号驱动能力的&#xff0c;用于增大驱动能力 输入 读取端口的…

初识C语言·内存函数

目录 1 memcpy的使用和模拟实现 2 memmove的使用和模拟实现 3 memset的使用和模拟实现 4 memcmp的使用和模拟实现 1 memcpy的使用和模拟实现 紧接字符串函数&#xff0c;出场的是第一个内存函数memcpy。前面讲的字符串函数是专门干关于字符串的事的&#xff0c;而这个函数…

如何使用程序控制微信发送消息

简介 使用杨中科老师的nuget包NetAutoGUI&#xff0c;控制微信给指定用户发送消息&#xff0c;如果想下面视频一样使用此功能用来轰炸朋友&#xff0c;可以直接跳到最后一节&#xff0c;或者直接下载我的打包好的程序集 【免费】控制微信发送消息的程序资源-CSDN文库 微信轰炸…

蓝桥杯备赛 | 洛谷做题打卡day5

蓝桥杯备赛 | 洛谷做题打卡day5 图论起航&#xff0c;一起来看看深&#xff08;广&#xff09;度优先吧 ~ 文章目录 蓝桥杯备赛 | 洛谷做题打卡day5图论起航&#xff0c;一起来看看深&#xff08;广&#xff09;度优先吧 ~【深基18.例3】查找文献题目描述 输入格式输出格式样例…

《如何制作类mnist的金融数据集》——1.数据集制作思路

1&#xff0e;数据集制作思路&#xff08;生成用于拟合金融趋势图像的分段线性函数&#xff09; 那么如何去制作这样的一个类minist的金融趋势曲线数据集呢&#xff1f; 还是如上图所示&#xff0c;为了使类别平均分布&#xff0c;因此可以选取三种“buy”的曲线、三种“sell”…

Web前端 ---- 【Vue3】computed计算属性和watch侦听属性(侦听被ref和reactive包裹的数据)

目录 前言 computed watch watch侦听ref数据 ref简单数据类型 ref复杂数据类型 watch侦听reactive数据 前言 本文介绍在vue3中的computed计算属性和watch侦听属性。介绍watch如何侦听被ref和reactive包裹的数据 computed 在vue3中&#xff0c;计算属性computed也是组合式…

C语言天花板——指针(经典题目)

指针我们已经学习的差不多了&#xff0c;今天我来给大家分享几个经典的题目&#xff0c;来让我们相互学习&#x1f3ce;️&#x1f3ce;️&#x1f3ce;️ int main() {int a[4] { 1, 2, 3, 4 };int* ptr1 (int*)(&a 1);int* ptr2 (int*)((int)a 1);printf("%x,%…

Java重修第六天—面向对象3

通过学习本篇文章可以掌握如下知识 1、多态&#xff1b; 2、抽象类&#xff1b; 3、接口。 之前已经学过了继承&#xff0c;static等基础知识&#xff0c;这篇文章我们就开始深入了解面向对象多态、抽象类和接口的学习。 多态 多态是在继承/实现情况下的一种现象&#xf…