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

简介: 本文是《算法-从菜鸟开始》系列文章的第7篇,欢迎收藏、留言、点赞。话不多说,让我们继续我们的算法之旅。

一、LeetCode 6. Z 字形变换


题目介绍:


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


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


P   A   H   N
A P L S I I G
Y   I   R


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

如:"PAHNAPLSIIGYIR"。


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


string convert(string s, int numRows);


示例:


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


二、解题分析


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


到底是弄啥类?!


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


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


  1. 从字符串s中取出一个放入当前行,再次取出一个放入下一行,重复这个行为;


  1. 直到numRows - 1行,放置完成后;


  1. 接下来该调整方向,往上一行放一个;


  1. 继续向上,直到第0行,调整方向,往下一行放一个。


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


  1. 只需要1行时,直接返回字符串即可。


  1. 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('');
};


网络异常,图片无法展示
|


三、总结


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


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


TIPS:


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


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



相关文章
|
1月前
|
算法 Java
[Java·算法·简单] LeetCode 27. 移除元素 详细解读
[Java·算法·简单] LeetCode 27. 移除元素 详细解读
23 1
|
1月前
|
算法 Java
[Java·算法·简单] LeetCode 13. 罗马数字转整数 详细解读
[Java·算法·简单] LeetCode 13. 罗马数字转整数 详细解读
22 0
|
1月前
|
算法 Java
[Java·算法·简单] LeetCode 392. 判断子序列 详细解读
[Java·算法·简单] LeetCode 392. 判断子序列 详细解读
24 0
|
1月前
|
存储 canal 算法
[Java·算法·简单] LeetCode 125. 验证回文串 详细解读
[Java·算法·简单] LeetCode 125. 验证回文串 详细解读
23 0
|
1月前
|
算法 Java
[Java·算法·中等] LeetCode15. 三数之和
[Java·算法·中等] LeetCode15. 三数之和
30 0
|
1月前
|
算法 Java
[Java·算法·简单] LeetCode 28. 找出字符串中第一个匹配项的下标 详细解读
[Java·算法·简单] LeetCode 28. 找出字符串中第一个匹配项的下标 详细解读
21 0
|
1月前
|
算法 Java
[Java·算法·简单] LeetCode 14. 最长公共前缀 详细解读
[Java·算法·简单] LeetCode 14. 最长公共前缀 详细解读
20 0
|
1月前
|
算法 Java 索引
[Java·算法·简单] LeetCode 141. 环形链表 详细解读
[Java·算法·简单] LeetCode 141. 环形链表 详细解读
23 0
|
1月前
|
存储 算法 Java
[Java·算法·简单] LeetCode 383. 赎金信 详细解读
[Java·算法·简单] LeetCode 383. 赎金信 详细解读
19 0
|
1月前
|
算法 Java 索引
[Java·算法·中等] LeetCode122. 买股票的最佳时机 II 解读
[Java·算法·中等] LeetCode122. 买股票的最佳时机 II 解读
21 0