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] 6. ZigZag Conversion 之字型转换字符串的更多相关文章

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

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

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

    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. ZigZag Conversion(找规律,水题)

    6. ZigZag Conversion Medium The string "PAYPALISHIRING" is written in a zigzag pattern on ...

  5. LeetCode 6. ZigZag Conversion & 字符串

    ZigZag Conversion 看了三遍题目才懂,都有点怀疑自己是不是够聪明... 就是排成这个样子啦,然后从左往右逐行读取返回. 这题看起来很简单,做起来,应该也很简单. 通过位置计算行数: P ...

  6. leetcode:ZigZag Conversion 曲线转换

    Question: The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of ...

  7. LeetCode 6 ZigZag Conversion 模拟 难度:0

    https://leetcode.com/problems/zigzag-conversion/ The string "PAYPALISHIRING" is written in ...

  8. LeetCode 6 ZigZag Conversion(规律)

    题目来源:https://leetcode.com/problems/zigzag-conversion/ The string "PAYPALISHIRING" is writt ...

  9. [LeetCode][Python]ZigZag Conversion

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com'https://oj.leetcode.com/problems/zigzag- ...

随机推荐

  1. NXP官方的i.mx6ul板级uboot源码适配

    1.前言 CoM-P6UL是盈鹏飞科技有限公司基于NXP原厂I.MX6UL芯片生产研发的核心板,本文将对CoM-P6UL适配NXP的基于Linux4.1.15版本的uboot板级源码. 2.开发环境 ...

  2. Vue.js 源码分析(二十一) 指令篇 v-pre指令详解

    该指令会跳过所在元素和它的子元素的编译过程,也就是把这个节点及其子节点当作一个静态节点来处理,例如: <!DOCTYPE html> <html lang="en" ...

  3. java构建树形列表(带children属性)

    一些前端框架提供的树形表格需要手动构建树形列表(带children属性的对象数组),这种结构一般是需要在Java后台构建好. 构建的方式是通过id字段与父id字段做关联,通过递归构建children字 ...

  4. 【转载】百度百科:FusionCube超融合

    [转载]百度百科:FusionCube超融合 华为FusionCube融合基础设施一体机(Huawei FusionCube Converged Infrastructure)是华为公司IT产品线云计 ...

  5. 进程间通信的信道与控制(io机制)

    进程间通信 = 信道 + 控制(状态) + io 信道: 1.流式信道: 2.队列信道: 3.共享内存信道: 控制机制: 数据就绪状态的通知与数据获取机制. 1.信号: 2.循环: 3.io机制

  6. 在QT中使用FFmpeg库的部分报错问题

    win32: LIBS += -L$$PWD/../ffmpeg-win32-dev/lib/ -lavutil win32: LIBS += -L$$PWD/../ffmpeg-win32-dev/ ...

  7. SQLi-LABS Page-1(Basic Challenges) Less1-Less4

    Less-1 GET - Error based - Single quotes - Stri http://10.10.202.112/sqli/Less-1?id=1 http://10.10.2 ...

  8. LearnOpenGL.PBR.光照

    光源辐射率:      辐射率(radiance)表示光源在给定立体角ω下的辐射通量(或光源发射的能量).     那么假设立体角ω无限小时,辐射率就表示单束光线(或说某个单一方向)的辐射通量. 点光 ...

  9. Rust中的Trait

    类似接口,但和php中的trait又有点不一样. pub trait Summary { fn summarize(&self) -> String; } pub struct NewA ...

  10. JS高阶---原型面试

    测试1: 分析如下 结果如下: 测试2: 测试3: 测试4: .