【面试经典 150 | 数组】Z 字形变换

文章目录

  • 写在前面
  • Tag
  • 题目来源
  • 解题思路
    • 方法一:二维矩阵模拟
    • 方法二:一次遍历
  • 写在最后

写在前面

本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更……

专栏内容以分析题目为主,并附带一些对于本题涉及到的数据结构等内容进行回顾与总结,文章结构大致如下,部分内容会有增删:

  • Tag:介绍本题牵涉到的知识点、数据结构;
  • 题目来源:贴上题目的链接,方便大家查找题目并完成练习;
  • 题目解读:复述题目(确保自己真的理解题目意思),并强调一些题目重点信息;
  • 解题思路:介绍一些解题思路,每种解题思路包括思路讲解、实现代码以及复杂度分析;
  • 知识回忆:针对今天介绍的题目中的重点内容、数据结构进行回顾总结。

Tag

【字符串】【二维矩阵模拟】【一次遍历】


题目来源

6. Z 字形变换


解题思路

方法一:二维矩阵模拟

一种朴素的解法是将字符串 s 按其形状填写到二维矩阵上,然后逐行遍历句还早呢中的非空字符,组成答案。

二维矩阵的行和列分别为多少?行数就是 r,列数需要花点时间计算一下。

n 为字符串 s 的长度,r = numRows。对于特殊情况,字符串只有一行(r = 1)或者只有一列(r >= n),直接返回 s

根据题意,当我们在矩阵上填写字符时,会向下(前文图片中竖的方向)填写 r 个字符,然后向右上(斜的方向)填写 r - 2 个字符,最后回到一行。于是可以清楚的知道 Z 字形变换的周期 t = r + r - 2 = 2r - 2,每个周期会占据矩阵中的 1 + r - 2 = r - 1 列。

因此我们有 ⌈ n t ⌉ \lceil{\frac{n}{t}}\rceil tn 个周期,乘上每个周期的列数,于是可以得到矩阵的列数为 c = ⌈ n t ⌉ ⋅ ( r − 1 ) c = \lceil{\frac{n}{t}}\rceil \cdot (r-1) c=tn(r1)

创建一个 rc 列的矩阵,现在根据字符串的下标 i 来更新矩阵的 xy 列。具体地初始化 (x, y) = (0, 0)

  • i % t < r - 1,说明现在的字符处在 “竖” 阶段,接着向下移动;
  • 否则,说明现在的字符处在 “斜” 阶段,需要更新 --x, ++y

代码

class Solution {
public:string convert(string s, int r) {int n = s.size();if (r == 1 || r >= n) {return s;} int t = 2*r - 2;    // 一个周期的字符数int c = (n + t - 1) / t * (r - 1);vector<string> mat(r, string(c, 0));for (int i = 0, x = 0, y = 0; i < n; ++i) {mat[x][y] = s[i];if (i % t < r - 1) {++x;}else {--x;++y;}}string res;for (auto& row : mat) {for (char c : row) {if (c) {res += c;}}}return res; }
};

复杂度分析

时间复杂度: O ( r ⋅ n ) O(r \cdot n) O(rn) r = n u m R o w s r = numRows r=numRows n n n 为字符串 s 的长度。

空间复杂度: O ( r ⋅ n ) O(r \cdot n) O(rn)

方法二:一次遍历

思路

注意到每次往矩阵的某一行添加字符时,都会添加到该行上一个字符的右侧,且最后组成答案时只会用到每行的非空字符。因此我们可以将矩阵的每行初始化为一个空列表,每次向某一行添加字符时,添加到该行的列表末尾即可。

并且维护一个 bool 变量表示现在下一次操作是更新下一行还是上一行的字符串,若为 true 更新下一行,否则更新上一行。

代码

class Solution {
public:string convert(string s, int r) {int n = s.size();if (r == 1 || r >= n)return s;vector<string> rows(r);bool goingDown = false;int curRow = 0;for (char c : s) {rows[curRow] += c;if (curRow == 0 || curRow == r - 1)goingDown = !goingDown;curRow += goingDown ? 1 : -1;}string ret;for (string row : rows)ret += row;return ret;}
};

复杂度分析

时间复杂度: O ( n ) O(n) O(n) n n n 为字符串 s 的长度。

空间复杂度: O ( n ) O(n) O(n)


写在最后

如果您发现文章有任何错误或者对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度的方法,欢迎评论区交流。

最后,感谢您的阅读,如果有所收获的话可以给我点一个 👍 哦。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CouchDB 与 PouchDB】

CouchDB是什么 CouchDB&#xff0c;全名为Apache CouchDB&#xff0c;是一个开源的NoSQL数据库&#xff0c;由Apache软件基金会管理。CouchDB的主要特点是使用JSON作为存储格式&#xff0c;使用JavaScript作为查询语言&#xff08;通过MapReduce函数&#xff09;&#xff0c;并…

QT中基于TCP的网络通信

QT中基于TCP的网络通信 QTcpServer公共成员函数信号 QTcpSocket公共成员函数信号 通信流程服务器端通信流程代码 客户端通信流程代码 使用Qt提供的类进行基于TCP的套接字通信需要用到两个类&#xff1a; QTcpServer&#xff1a;服务器类&#xff0c;用于监听客户端连接以及和客…

赛劲SEJINIGB零背隙滚轮齿条齿圈产品助力高精度运动平台

在高度精密化的工业时代&#xff0c;传统齿轮齿条系统所面临的背隙、摩擦粉尘、润滑等问题愈发凸显&#xff0c;这些问题不仅限制了设备的精度和稳定性&#xff0c;还对生产效率和产品质量造成严重影响。为此&#xff0c;赛劲SEJINIGB经过长期研发和技术积累&#xff0c;推出了…

消息队列 Kafka 入门篇(二) -- 安装启动与可视化工具

一、Windows 10 环境安装 1、下载与解压 首先&#xff0c;访问Apache Kafka的官方下载地址&#xff1a; https://kafka.apache.org/downloads 在本教程中&#xff0c;我们将使用kafka_2.13-2.8.1版本作为示例。下载完成后&#xff0c;解压到您的工作目录的合适位置&#xff…

ubuntu下chronyc tracking报文详解

在ubuntu下使用chronyc进行时钟的同步操作&#xff0c;下面是执行chrony tracking返回结果&#xff1a; Reference ID : AC1005E7 (ntpxx) Stratum : 12 Ref time (UTC) : Tue Apr 23 07:24:09 2024 System time : 0.000001974 seconds slow of NTP time Last …

如何在Windows 8/10/11上启用和禁用内置访客帐户?这里提供几种方法

你的Windows上有一个内置的guest帐户&#xff0c;可以帮助计算机上没有帐户的人登录。当然&#xff0c;你可以打开或关闭它。本文将介绍一些在Windows 8/10/11计算机中启用和禁用内置guest帐户的有用方法&#xff0c;供你更好地参考。 如何启用内置来宾帐户 在本地组策略中启…

Django中的事务

1 开启全局的事务 DATABASES {default: {ENGINE: django.db.backends.mysql, # 使用mysql数据库NAME: tracerbackend, # 要连接的数据库USER: root, # 链接数据库的用于名PASSWORD: 123456, # 链接数据库的用于名HOST: 192.168.1.200, # mysql服务监听的ipPORT: 3306, …

面向多源异质遥感影像地物分类的自监督预训练方法

源自&#xff1a;测绘学报 作者&#xff1a;薛志祥, 余旭初, 刘景正, 杨国鹏, 刘冰, 余岸竹, 周嘉男, 金上鸿 摘 要 近年来,深度学习改变了遥感图像处理的方法。由于标注高质量样本费时费力,标签样本数量不足的现实问题会严重影响深层神经网络模型的性能。为解决这一突出矛盾…

Linux防火墙相关命令以及ip白名单配置

Linux防火墙相关命令以及ip白名单配置 firewall防火墙基础命令查看防火墙的服务状态查看防火墙的状态服务的开启、关闭和重启查看防火墙规则端口的查询、开放和关闭重启防火墙 防火墙白名单配置部分参数介绍 firewall防火墙基础命令 查看防火墙的服务状态 systemctl status f…

使用 vllm 本地部署 cohere 的 command-r

使用 vllm 本地部署 cohere 的 command-r 0. 引言1. 安装 vllm2. 本地部署 cohere 的 command-r3. 使用 cohere 的 command-r 0. 引言 此文章主要介绍使用 使用 vllm 本地部署 cohere 的 command-r。 1. 安装 vllm 创建虚拟环境&#xff0c; conda create -n myvllm python…

nn.Embedding, nn.Parameter,nn.linear的区别

还没总结&#xff1a; 先贴上参考帖子&#xff1a; Difference between Embedding formulations Issue #60 lucidrains/vit-pytorch GitHub https://audreywongkg.medium.com/pytorch-nn-parameter-vs-nn-linear-2131e319e463 Differences between nn.Embedding and nn.…

网络安全之CSRFSSRF漏洞(上篇)(技术进阶)

目录 一&#xff0c;CSRF篇 二&#xff0c;认识什么是CSRF 三&#xff0c;实现CSRF攻击的前提 四&#xff0c;实战演练 【1】案例1 【2】案例2 【3】案例3 【4】案例4&#xff08;metinfo&#xff09; 一&#xff0c;CSRF篇 二&#xff0c;认识什么是CSRF CSRF&#x…

Diff算法深度剖析:优化DOM操作的关键

React的Diff算法是用于比较新旧虚拟DOM树&#xff0c;以找出需要进行更新的部分。它通过遍历树的节点&#xff0c;并比较节点属性和内容&#xff0c;来确定节点是否需要进行更新。 React的Diff算法采用了一些优化策略&#xff0c;以减少不必要的DOM更新&#xff0c;提高性能。…

程序员过了35岁没人要?“这行越老越香”

程序员35岁失业&#xff1f;参加完OceanBase开发者大会&#xff0c;我又悟了&#xff01; 周六参加了OceanBase2024 开发者大会的现场&#xff0c;来之前我其实挺忐忑的&#xff0c;我觉得一个数据库产品的发布会&#xff0c;能有什么新鲜的东西&#xff1f; 踏入酒店的那一刻&…

vue 动态改变css样式

文章目录 问题描述 问题描述 大家好&#xff01;今天是2024年4月26日|农历三月十六&#xff0c;时间过得好快&#xff0c;今天这博文主要动态改变css样式&#xff0c;具体实现效果如下&#xff1a; 在data里面声明一个isShow:true属性&#xff0c;通过isShow显示不同的图片 isS…

RouteRecordRaw

最近在学习并使用typescript&#xff0c;接触到了很多新类型&#xff0c;今天在学习过程中&#xff0c;看到了RouteRecordRaw这个类型&#xff0c;写篇博客记录一下。 RouteRecordRaw RouteRecordRaw 是 Vue Router 4 中新增的一个类型定义。 它是用于定义路由记录的。 在 Vu…

Pinia 深度剖析:Vue.js 应用状态管理的全面指南

一、pinia简介 Pinia 是一个专门为 Vue.js 应用程序设计的状态管理库。它的设计理念是简化状态管理过程&#xff0c;提供一种清晰、可维护的方式来管理应用程序中的数据。 二、安装与创建 1.你可以通过 npm 或者 yarn 来安装 Pinia&#xff1a; npm install pinia # 或者 y…

上位机工作感想-从C#到Qt的转变-2

2.技术总结 语言方面 最大收获就是掌握了C Qt编程&#xff0c;自己也是粗看了一遍《深入理解计算机系统》&#xff0c;大致了解了计算机基本组成、虚拟内存、缓存命中率等基基础知识&#xff0c;那本书确实有的部分看起来很吃力&#xff0c;等这段时间忙完再研读一遍。对于封装…

消消乐算法总结

前言 最近在工作中遇到一个问题&#xff0c;做一个消消乐的demo项目&#xff0c;连续相同数目超过四个后就要消除。我在网上看了很多解决方案&#xff0c;有十字形&#xff0c;横向&#xff0c;纵向&#xff0c;梯形搜索。越看越迷糊。这不是用一个BFS就能解决的问题吗&#x…

linux下tcp/udp协议网络通信接口封装+日志打印对象

目录 引入 代码 log.hpp代码 引入 我们可以把之前写过的代码拿过来整合一下,直接封装出网络套接字的接口 这样之后再使用的话,直接调用接口即可这里写的是tcp协议,也可以修改socket函数里的参数,改为udp协议 代码 #pragma once#include <iostream> #include <stri…