0
点赞
收藏
分享

微信扫一扫

LeetCode 6. Z 字形变换 | 算法-从菜鸟开始


算法,从承认自己是一个菜鸟开始!

本文是《算法-从菜鸟开始》系列文章的第7篇,欢迎​​收藏​​​、​​留言​​​、​​点赞​​。

话不多说,让我们继续我们的算法之旅。

一、LeetCode 6. Z 字形变换

题目介绍:

将一个给定字符串 ​​s​​​ 根据给定的行数 ​​numRows​​ ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:

P   A   H   NA P L S I I GY   I   R

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

示例:

输入: s = "PAYPALISHIRING", numRows = 3输出: "PAHNAPLSIIGYIR"

二、解题分析

这道算法题是非常有意思的,因为大多数的同学在第一次看到的时候根本就弄不明白,这个到底是在干啥。

到底是弄啥类?!

分析这道题时有一个诀窍,就是要把这个题目介绍中的​​Case​​​当成古代的​​武林秘籍​​​看,不同于现在文字横写的方式,古代武林秘籍是采用垂直​​竖​​写的方式。

如果换个视角,采用​​竖​​着,一列一列来来看题目,表现为:

  1. 从字符串​​s​​中取出一个放入当前行,再次取出一个放入下一行,重复这个行为;
  2. 直到​​numRows - 1​​行,放置完成后;
  3. 接下来该调整方向,往上一行放一个;
  4. 继续向上,直到第0行,调整方向,往下一行放一个。

同时要考虑特殊的情况,比如:

  1. 只需要1行时,直接返回字符串即可。
  2. 当​​s.length <= numRows​​即字符串长度小于行数时,也可以直接返回当前字符串。

基于以上的分析,我们来看代码的实现:

/**
* @param {string} s
* @param {number} numRows
* @return {string}
*/
var convert = function(s, numRows) {
// 特殊Case判定
if (s.length < numRows || numRows === 1) {
return s;
}

// 定义数组rows,对应存储每一行的字符串
const rows = []

// 使用变量i,表示rows的下标,代表了每一行
let i = 0;

// 使用变量j,表示字符串s的下标
let j = 0;

// 定义当前的填充字符的方向,-1表示向上,1表示向下
// 注意这里的初始值设置为-1,有特殊作用
let dir = -1;

// 遍历字符串,将每一个字符放入到对应的每一行中
while (j < s.length) {
// 要注意,对应的每一个i行,都是要拼接上最新的字符。
// 注意初rows[i]是否存在
rows[i] = rows[i] ? rows[i] += s[j] : s[j];

// 调整方向判定条件:第0行以及第numRows - 1行
if (i === 0 || i === numRows - 1) {
// 如果调整方向呢,当前值 *= -1即发生反向
dir *= -1;
}

// 当前行数发生变化
i += dir;

// 变量j发生变化,继续遍历子串s
j++;
}

// 将数组中的每行字符串再次进行拼接,并返回
return rows.join('');
};

LeetCode 6. Z 字形变换 | 算法-从菜鸟开始_字符串长度

三、总结

整体来看,这道算法题的问题主要集中于如何理解这个​​Z​​字型展示的问题,分析展示的特点。得出展示的规律就好理解这个问题了。

当然解决这个问题的算法有很多种,比如去观察每一行字母的下标规律,出现的特点,也是可以计算的。欢迎大家多多动手尝试。

TIPS:

在JS中,我们经常使用 ​​*= -1​​的形式,来调整方向,尤其是在动画相关实现中。

算法-从菜鸟开始,而无止境。与君共勉!

举报

相关推荐

0 条评论