The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

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

And then read line by line: "PAHNAPLSIIGYIR"

Write the code that will take a string and make this conversion given a number of rows:

string convert(string s, int numRows);

Example 1:

Input: s = "PAYPALISHIRING", numRows = 3
Output: "PAHNAPLSIIGYIR"

Example 2:

Input: s = "PAYPALISHIRING", numRows = 4
Output: "PINALSIGYAHRPI"
Explanation: P I N
A L S I G
Y A H R
P I

这道题刚开始看了半天没看懂是咋样变换的,上网查了些资料,终于搞懂了,就是要把字符串摆成一个之字型的,比如有一个字符串 "0123456789ABCDEF",转为 zigzag 如下所示:

当 n = 2 时:

0 2 4 6 8 A C E

1 3 5 7 9 B D F

当 n = 3 时:

0   4    8     C

1 5 9 B D F

2    6   A     E

当 n = 4 时:

0     6        C

1   7   B  D

2   8 A    E

3      9       F

可以发现,除了第一行和最后一行没有中间形成之字型的数字外,其他都有,而首位两行中相邻两个元素的 index 之差跟行数是相关的,为  2*nRows - 2, 根据这个特点,可以按顺序找到所有的黑色元素在元字符串的位置,将他们按顺序加到新字符串里面。对于红色元素出现的位置(Github 上可能无法正常显示颜色,请参见博客园上的帖子)也是有规律的,每个红色元素的位置为 j + 2 x numRows-2 - 2 x i, 其中,j为前一个黑色元素的 index,i为当前行数。 比如当 n = 4 中的那个红色5,它的位置为 1 + 2 x 4-2 - 2 x 1 = 5,为原字符串的正确位置。知道了所有黑色元素和红色元素位置的正确算法,就可以一次性的把它们按顺序都加到新的字符串里面。代码如下:

解法一:

class Solution {
public:
string convert(string s, int numRows) {
if (numRows <= ) return s;
string res;
int size = * numRows - , n = s.size();
for (int i = ; i < numRows; ++i) {
for (int j = i; j < n; j += size) {
res += s[j];
int pos = j + size - * i;
if (i != && i != numRows - && pos < n) res += s[pos];
}
}
return res;
}
};

若上面解法中的规律不是很好想的话,我们也可以用下面这种更直接的方法来做,建立一个大小为 numRows 的字符串数组,为的就是把之字形的数组整个存进去,然后再把每一行的字符拼接起来,就是想要的结果了。顺序就是按列进行遍历,首先前 numRows 个字符就是按顺序存在每行的第一个位置,然后就是 ‘之’ 字形的连接位置了,可以发现其实都是在行数区间 [1, numRows-2] 内,只要按顺序去取字符就可以了,最后把每行都拼接起来即为所求,参见代码如下:

解法二:

class Solution {
public:
string convert(string s, int numRows) {
if (numRows <= ) return s;
string res;
int i = , n = s.size();
vector<string> vec(numRows);
while (i < n) {
for (int pos = ; pos < numRows && i < n; ++pos) {
vec[pos] += s[i++];
}
for (int pos = numRows - ; pos >= && i < n; --pos) {
vec[pos] += s[i++];
}
}
for (auto &a : vec) res += a;
return res;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/6

类似题目:

Zigzag Iterator

Binary Tree Zigzag Level Order Traversal

参考资料:

https://leetcode.com/problems/zigzag-conversion/

https://www.cnblogs.com/springfor/p/3889414.html

https://leetcode.com/problems/zigzag-conversion/discuss/3403/Easy-to-understand-Java-solution

https://leetcode.com/problems/zigzag-conversion/discuss/3417/A-10-lines-one-pass-o(n)-time-o(1)-space-accepted-solution-with-detailed-explantation

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] ZigZag Converesion 之字型转换字符串的更多相关文章

  1. [LeetCode] 6. ZigZag Converesion 之字型转换字符串

    The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like ...

  2. [LeetCode] 6. ZigZag Conversion 之字型转换字符串

    The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like ...

  3. LeetCode OJ:ZigZag Conversion(字符串的Z字型转换)

    The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like ...

  4. leetcode 6/300 Z字型变换 py

    目录 题目说明 方法一:利用flag 题目说明 方法一:利用flag 简单来说就是利用flag来表示方向,真的神来之笔. class Solution: def convert(self, s: st ...

  5. 281. Zigzag Iterator z字型遍历

    [抄题]: Given two 1d vectors, implement an iterator to return their elements alternately. Example: Inp ...

  6. 剑指offer从上往下打印二叉树 、leetcode102. Binary Tree Level Order Traversal(即剑指把二叉树打印成多行、层序打印)、107. Binary Tree Level Order Traversal II 、103. Binary Tree Zigzag Level Order Traversal(剑指之字型打印)

    从上往下打印二叉树这个是不分行的,用一个队列就可以实现 class Solution { public: vector<int> PrintFromTopToBottom(TreeNode ...

  7. 算法:Z字型(Zigzag)编排

    问题:给定 n 行和 m 列的二维数组矩阵.如图所示,以 ZIG-ZAG 方式打印此矩阵. 从对称的角度来看,通过反复施加滑行反射可以从简单的图案如线段产生规则的之字形. 主要思想:算法从(0, 0) ...

  8. lintcode:Matrix Zigzag Traversal 矩阵的之字型遍历

    题目: 矩阵的之字型遍历 给你一个包含 m x n 个元素的矩阵 (m 行, n 列), 求该矩阵的之字型遍历. 样例 对于如下矩阵: [ [1, 2, 3, 4], [5, 6, 7, 8], [9 ...

  9. PHP中IP地址与整型数字互相转换详解

    这篇文章主要介绍了PHP中IP地址与整型数字互相转换详解,本文介绍了使用PHP函数ip2long与long2ip的使用,以及它们的BUG介绍,最后给出自己写的两个算法,需要的朋友可以参考下 IP转换成 ...

随机推荐

  1. 利用Python进行数据分析(5) NumPy基础: ndarray索引和切片

    概念理解 索引即通过一个无符号整数值获取数组里的值. 切片即对数组里某个片段的描述. 一维数组 一维数组的索引 一维数组的索引和Python列表的功能类似: 一维数组的切片 一维数组的切片语法格式为a ...

  2. 翻译:使用 ASP.NET MVC 4, EF, Knockoutjs and Bootstrap 设计和开发站点 - 2

    我们的目标: 需求 Screen 1: 联系人列表 - 查看所有联系人 1.1 这个 screen 将显示数据库中的所有联系人. 1.2 用户可以删除任何联系人.1.3 用户可以编辑任何联系人的详细信 ...

  3. 【WCF】如何将WCF部署到远程服务器

    一.前言       最近需要将自己写的WCF服务部署到远程服务器上,也就是公网上.宿主是IIS,在配置成功之前遇到了很多问题,问题如下: 1. WCF该怎么宿主在IIS上,为何会出现 400 Bad ...

  4. ViEmu 3.6.0 过期 解除30天限制的方法

    下载:链接: http://pan.baidu.com/s/1c2HUuWw 密码: sak8 删除下面2个地方 HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{B9CDA4 ...

  5. Java全角、半角字符的关系以及转换

    如果搞明白了Java中全角字符和半角字符之间的关系,那他们之间的转换就不是个麻烦事儿.你只需要对这个关系有那么一个印象就足够了. 全角字符与半角字符的关系 通过下面的代码能看到Java中所有字符以及对 ...

  6. 理解Java对象的交互:时钟显示程序

    实现: 结构: 对象:时钟  - 对象:小时                 - 对象:分钟 小时和分钟具有相同属性(值,上限),可以用一个类Display来定义这两个对象: 但是两者之间又具有联系( ...

  7. react-echarts之折线图的显示

    react中想要实现折线图和饼图的功能,需要引入react-echarts包,然后再实现折线图的功能.我这里引用的版本是:0.1.1.其他的写法参echarts官网即可.下面详细讲解的是我在react ...

  8. 后端Java工程师常用JavaScript_DOM

    JavaScript [1]事件 ①用户操作网页或者浏览器所发生的交互行为称为事件.比如:点击按钮,最小化窗口,修改文本框内容等. ②JS为我们定义许多浏览器中的事件.比如:单击(onclick).双 ...

  9. 【centos7】添加开机启动服务/脚本

    一.添加开机自启服务 在centos7中添加开机自启服务非常方便,只需要两条命令(以Jenkins为例): systemctl enable jenkins.service #设置jenkins服务为 ...

  10. 使用python处理子域名爆破工具subdomainsbrute结果txt

    近期学习了一段时间python,结合自己的安全从业经验,越来越感觉到安全测试是一个体力活.如果没有良好的coding能力去自动化的话,无疑会把安全测试效率变得很低. 作为安全测试而言,第一步往往要通过 ...