Fork me on GitHub

leetcode——[006]ZigZag Conversion Z字形变换

题目

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

1
string convert(string s, int numRows);

示例 1:

1
2
输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"

示例 2:

1
2
3
4
5
6
7
8
输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:

L D R
E O E I I
E C I H N
T S G

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)

1
2
3
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:

1
string convert(string s, int numRows);

Example 1:

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

Example 2:

1
2
3
4
5
6
7
8
Input: s = "PAYPALISHIRING", numRows = 4
Output: "PINALSIGYAHRPI"
Explanation:

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

解题方法

当字符串为空、numRows为1,字符串长度小于等于numRows时,直接返回字符串。

每(numRows-1) 2个字符是一个循环,以(numRows-1) 2为一个窗口,每次滑动(numRows-1) 2个字符。对每个窗口,除去第一行和最后一行,每行有两个字符,假设行数为i,每行第一个字符在原字符串中的位置关系不变,仍然是i;第二字符是对应原字符串的(numRows-1) 2 - i位置,即第一个字符的偏置为(numRows-1-i) * 2。为了保持结果字符顺序的正确性,所以按行数循环,窗口从字符串开头滑动到末尾,每次只处理一行的字符。所以滑动窗口循环了numRows次。

这段代码跑了13ms,超过了96.85%的Java提交。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution{
// Method 1 13ms 96.85%
public String convert(String s, int numRows) {
if (s == null || s.length() <= numRows || numRows == 1) {
return s;
}
StringBuilder res = new StringBuilder();
for (int i = 0; i < numRows; i++) {
for (int j = i; j < s.length(); j += (numRows-1) * 2) {
res.append(s.charAt(j));
if (i > 0 && i < numRows - 1 && j+(numRows-1-i) * 2 < s.length()) {
res.append(s.charAt(j+(numRows-1-i)*2));
}
}
}
return res.toString();
}
}
BJTU-HXS wechat
海内存知己,天涯若比邻。