【力扣】Z 字形变换,模拟 + 直接构造

Z 字形变换原题地址

方法一:利用二维矩阵模拟

对于特殊情况,Z 字形变换后只有一行或只有一列,则变换后的字符串和原字符串相同。

对于一般情况,我们可以考虑按照题目要求,把字符串按照 Z 字形存储到二维数组中,再横向遍历所有有效字符

假设 Z 字形变换后的矩阵有 r 行,原字符串的长度为 n 。

Z 字形变换是按照周期 t 先向下,再向右上运动。一个周期 t=r+(r-2)=r*2-2 

其中 r-2 不包含两个红圈的位置。 一个周期 t 内的行数为 r 行,列数为 1+(r-2)=r-1 列,即最左边的一列以及中间的 r-2 列。矩阵的周期数为 \left \lceil \frac{n}{t} \right \rceil ,即 (n+t-1)/t ,加上的 t-1 是为了向上取整。矩阵的总列数为 周期数 * 每个周期的列数,即 c=(n+t-1)/t*(r-1) 

那么,什么时候向下走,什么时候向右上方走呢?这要看当前处在周期的什么位置。假设当前遍历到下标为 i 的字符,如果 imodt<r-1 ,即当前处在周期的前 r-1 个位置,就需要向下走,否则就要向右上方走

// 方法一:利用二维矩阵模拟
class Solution
{
public:string convert(string s, int numRows){int n = s.size();int r = numRows; // 行数// 只有一行或者只有一列if (r == 1 || r >= n){return s;}// 周期 t=r+r-2int t = r * 2 - 2;// 一共有 (n/t) 向上取整 个周期// 即 (n+t-1)/t 个周期// 每个周期有 1+r-2=r-1 列int c = (n + t - 1) / t * (r - 1); // 列数// 构造矩阵,即 r 个 string 的数组,每个 string 的长度为 cvector<string> mat(r, string(c, 0));int x = 0, y = 0; // 左上角for (int i = 0; i < n; ++i){mat[x][y] = s[i];// 周期前 r-1 次都是向下移动// 否则向右上方移动if (i % t < r - 1){++x;}else{--x;++y;}}string ans;// 拼接每行有效字符for (auto& row : mat){for (auto ch : row){if (ch){ans += ch;}}}return ans;}
};

方法二:压缩矩阵空间

模拟时,可以不按照 Z 字形存储到矩阵中,而是根据当前字符在第几行,就存储在该行的最后一个位置,即尾插到当前行。这样的话可以节省矩阵的空间。

如果采用这种方案,就只需要考虑是向下走还是向上走。按照相同的思路,当 imodt<r-1 ,即当前周期的前 r-1 个字符,需要向下走,反之就向上走。

// 方法二:压缩矩阵空间
class Solution
{
public:string convert(string s, int numRows){int n = s.size();int r = numRows; // 行数// 只有一行或只有一列if (r == 1 || r >= n){return s;}vector<string> mat(r);// 周期 t=r+r-2int t = r * 2 - 2;int x = 0; // 在第几个 string 后面添加字符for (int i = 0; i < n; ++i){mat[x] += s[i];// 每个周期前 r-1 次向下移动if (i % t < r - 1){++x;}else{--x;}}string ans;// 拼接所有行for (auto& row : mat){ans += row;}return ans;}
};

方法三:方法二的另一种写法

在考虑是向下走还是向上走时,可以不用计算在当前周期的第几个位置,而是直接判断当前所处位置是否在最上面还是最下面。也就是说,如果当前在第 x 行,若 x==1 或者 x==r-1 ,说明要转向本来是向下走就要转为向上走,本来是向上走就要转为向下走

我们可以定义一个 flag ,如果 flag=1 代表向下走, flag=-1 代表向上走,每次只需要 x+=flag 就能求出新的所在行 x 了。如果要转向,只需执行 flag=-flag 

// 方法三:方法二的另一种写法,利用 flag 记录何时转向
class Solution
{
public:string convert(string s, int numRows){int n = s.size();int r = numRows; // 行数// 只有一行或只有一列if (r == 1 || r >= n){return s;}vector<string> mat(r);int x = 0; // 在第几个 string 后面添加字符int flag = 1; // 行转向标志, 1 代表向下走, -1 代表向上走for (int i = 0; i < n; ++i){mat[x] += s[i];x += flag;// 转向if (x == r - 1 || x == 0){flag = -flag;}}string ans;// 拼接所有行for (auto& row : mat){ans += row;}return ans;}
};

方法四:直接构造

前三种方法都需要构造一个新的矩阵来模拟,我们可以考虑直接构造,也就是直接取出原字符串的字符来构造 ans 字符串。这就需要找出 Z 字形变换的规律,看图:

按照“Z字形”的顺序来看,就是 0->1->2->3->...->t-2->t-1->t->t+1->t+2->...->2t-2->2t-1->2t->2t+1->2t+2->...

如果我们横着看呢? 我们用i来控制行, i 从 0 递增到 r-1 。再用 j 控制列, j 从 0 开始,每次递增 t ,也就是 0,t,2t,3t,... 。那么下图中,每个周期都是线 + 方框,线是 i+j ,框柱的是 j+t-i 

对于每一行,都有线,但是第 0 行和第 r-1 行没有方框内的元素,利用这点直接构造字符串即可。

// 方法四:直接构造
class Solution
{
public:string convert(string s, int numRows){int n = s.size();int r = numRows; // 行数// 只有一行或只有一列if (r == 1 || r >= n){return s;}string ans;// 周期 t=r+r-2int t = r * 2 - 2;for (int i = 0; i < r; ++i){for (int j = 0; j + i < n; j += t){// 当前周期第一个字符ans += s[j + i];// 若不是第一行和最后一行,还有第二个字符if (0 < i && i < r - 1 && j + t - i < n){ans += s[j + t - i];}}}return ans;}
};

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

做抖店想要快速起店怎么办?产品和流量是关键!新手可收藏!

大家好&#xff0c;我是电商小布。 在抖音小店开通完成后&#xff0c;大家考虑的第一件事情&#xff0c;一定是小店如何能够快速出单&#xff0c;成功起店。 店铺出单的重点&#xff0c;其实就在小店的运营上。 那么这么多的环节&#xff0c;关键点在哪呢&#xff1f; 答案…

大学生多媒体课程学习网站thinkphp+vue

开发语言&#xff1a;php 后端框架&#xff1a;Thinkphp 前端框架&#xff1a;vue.js 服务器&#xff1a;apache 数据库&#xff1a;mysql 运行环境:phpstudy/wamp/xammp等开发背景 &#xff08;一&#xff09; 研究课程的提出 &#xff08;二&#xff09;学习网站的分类与界定…

前端页面之间传输数据 localStorage

效果 发送方 接收方 localStorage 的使用 // 保存数据 localStorage.setItem(key, value); // 获取数据 localStorage.getItem(key);发送方 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>登录<…

【深蓝学院】移动机器人运动规划--第6章 模型预测控制(MPC)与运动规划--笔记

0. Outline 1. Reactive Control&#xff08;反应式控制&#xff09; 控制学中的 “Reactive Control” 通常指的是一种控制策略&#xff0c;它依赖于系统对特定事件或变化的即时反应&#xff0c;而不是按照预定的计划或策略行动。这种控制往往是基于当前的传感器输入来做出决…

c编译器学习07:minilisp编译器改造(debug模式支持调试)

问题 原版的minilisp编译器不支持argv输入测试&#xff0c;不方便单步调试。 代码改造目标是既不改变原有程序的各种功能&#xff0c; 又能支持个人习惯的vs单步debug模式。 CMakeLists.txt变更 定义DEBUG宏 解决单步调试源码定位偏差问题 cmake_minimum_required(VERSION …

【Android安全】Windows 环境下载 Android 源码

准备环境 安装 git 安装 Python 硬盘剩余容量最好大于 100G 打开 Git Bash&#xff0c;用 git 克隆源代码仓库 git clone https://android.googlesource.com/platform/manifest.git //没有梯子使用清华源 git clone https://aosp.tuna.tsinghua.edu.cn/platform/manifest.git…

RabbitMQ 部署方式选择

部署模式 RabbitMQ支持多种部署模式&#xff0c;可以根据应用的需求和规模选择适合的模式。以下是一些常见的RabbitMQ部署模式&#xff1a; 单节点模式&#xff1a; 最简单的部署方式&#xff0c;所有的RabbitMQ组件&#xff08;消息存储、交换机、队列等&#xff09;都运行在…

TensorRT及CUDA自学笔记003 NVCC及其命令行参数

TensorRT及CUDA自学笔记003 NVCC及其命令行参数 各位大佬&#xff0c;这是我的自学笔记&#xff0c;如有错误请指正&#xff0c;也欢迎在评论区学习交流&#xff0c;谢谢&#xff01; NVCC是一种编译器&#xff0c;基于一些命令行参数可以将使用PTX或C语言编写的代码编译成可…

新手如何自己建网站的详细步骤?-网站建设

新手如何自己建网站的详细步骤&#xff1f;-网站建设 我们选择了白嫖雨云的二级域名 浏览器输入https://www.rainyun.com/z22_ 创建账号然后选择一个你喜欢的子域名我建议后缀选择ates.top的 选择自定义地址&#xff0c;类型选择cname 现在要选择记录值了&#xff0c;有a&…

linux内核原理--页高速缓存,回写,页框回收

1.页高速缓存 我们主要分析下磁盘文件的页高速缓存 struct address_space {struct inode *host; struct radix_tree_root page_tree; spinlock_t tree_lock;unsigned int i_mmap_writable;struct prio_tree_root i_mmap; struct list_head i_mmap_nonlinear;spinlock_t i_…

2023最新简绘AI开源版支持MJ绘画,AI问答

应用介绍 本文来自&#xff1a;2023最新简绘AI开源版支持MJ绘画&#xff0c;AI问答 - 源码1688 简介&#xff1a; 简绘AI开源版&#xff0c;从闲鱼上买的&#xff0c;搭建教程如下 测试环境&#xff1a;NginxPHP7.4MySQL5.6 图片&#xff1a;

com.alibaba.nacos.api.exception.NacosException: Request nacos server failed

问题描述 安装nacos2.0以上版本&#xff0c;启动报错:com.alibaba.nacos.api.exception.NacosException: Request nacos server failed com.alibaba.nacos.api.exception.NacosException: Request nacos server failed: at com.alibaba.nacos.client.naming.remote.gprc.Nami…

2024022402-数据库恢复技术

数据库恢复技术 什么是事务 事务(Transaction)是用户定义的一个数据库操作序列&#xff0c;这些操作要么全做&#xff0c;要么全不做&#xff0c;是一个不可分割的工作单位 事务和程序是两个概念 在关系数据库中&#xff0c;一个事务可以是一条SQL语句&#xff0c;一组SQL语…

Movelt使用笔记-Movelt Setup Assistant

目录 Setup Assistant配置1 Start 加载urdf模型3 Virtual joints 虚拟关节5 Robot Poses 机器人位姿7 Passive Joints 被动关节8 Controllers 控制器9 Simulation 仿真10 3D Perception 3D感知11 Author Information 作者信息12 Configuration Files 配置文件启动MoveIt!Setup…

潇洒郎:2024 IDEA、Pycharm获取最新激活码获取方式

IDEA获取最新激活码 https://idea.javatiku.cn/ 手机打开&#xff0c;看到验证码&#xff0c;30分钟有效&#xff0c;输入验证码 获取到最新激活码

Vue.js+SpringBoot开发超市商品管理系统

目录 一、摘要1.1 简介1.2 项目录屏 二、研究内容2.1 数据中心模块2.2 超市区域模块2.3 超市货架模块2.4 商品类型模块2.5 商品档案模块 三、系统设计3.1 用例图3.2 时序图3.3 类图3.4 E-R图 四、系统实现4.1 登录4.2 注册4.3 主页4.4 超市区域管理4.5 超市货架管理4.6 商品类型…

IT廉连看——C语言——数组

IT廉连看——C语言——数组 一、一维数组的创建和初始化 1.1 数组的创建 数组是一组相同类型元素的集合。 数组的创建方式&#xff1a; type_t arr_name [const_n]; //type_t 是指数组的元素类型 //const_n 是一个常量表达式&#xff0c;用来指定数组的大小 数组创建…

onlyoffice api开发

编写代码 按照https://api.onlyoffice.com/editors/basic编写代码 <html> <head><meta charset"UTF-8"><meta name"viewport"content"widthdevice-width, user-scalableno, initial-scale1.0, maximum-scale1.0, minimum-scal…

Linux应用-ElasticSearch安装

ElasticSearch安装部署 简介 全文搜索属于最常见的需求&#xff0c;开源的 Elasticsearch &#xff08;以下简称 es&#xff09;是目前全文搜索引擎的首选。 它可以快速地储存、搜索和分析海量数据。维基百科、Stack Overflow、Github 都采用它。 Elasticsearch简称es&…

TLS握手证书链的校验

看一遍忘一遍&#xff0c;还是自己写一遍&#xff0c;看看这次能记多久。 在TLS握手过程中&#xff0c;通过证书校验认证服务端的身份和交换加密秘钥&#xff0c;握手完成之后后续就可以进行加密数据传输。 在浏览器地址栏上点击锁的图标&#xff0c;能打开查看证书的详细信息…