题目描述
将一个给定字符串 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);
-
示例 1:
输入:s = “PAYPALISHIRING”, numRows = 3
输出:“PAHNAPLSIIGYIR” -
示例 2:
输入:s = “PAYPALISHIRING”, numRows = 4
输出:“PINALSIGYAHRPI”
解释:P I N A L S I G Y A H R P I
-
示例 3:
输入:s = “A”, numRows = 1
输出:“A”
提示:
1 <= s.length <= 1000
s 由英文字母(小写和大写)、’,’ 和 ‘.’ 组成
1 <= numRows <= 1000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zigzag-conversion
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
直接写结论(将numRows简写为n):
- 第0行:0、0+(n-1)×2、0+(n-1)×2+(n-1)×2、…
- 第1行:1、1+(n-1-1)×2、1+(n-1-1)×2+1×2、…
- …
- 第i行:i、i+(n-1-i)×2、i+(n-1-i)×2+i×2、…
- …
- 第n-1行:n-1、n-1+(n-1)×2、n-1+(n-1)×2+(n-1)×2、…
即有一定的数学规律
另外如果字符串的长度小于等于numRows或者numRows=1,则直接返回字符串本身即可
代码详解
class Solution {
public String convert(String s, int numRows) {
if(s.length() <= numRows || numRows == 1) { // 两种特殊情况,可直接返回原字符串
return s;
}
StringBuilder sb = new StringBuilder();
for(int i = 0; i < numRows; ++i) { // 外循环仅对第0列的字符进行遍历
boolean flag = true; // 用于除第0行和第n-1行之外行数的代码块间交替执行
// 用上一小节总结的数学规律编写代码
int j = 0;
while(i + j < s.length()) { // 保证不越界
// 第0行和第n-1行的规律比较简单
if(i == 0 || i == numRows - 1) {
sb.append(s.charAt(i+j));
j += (numRows - 1) * 2;
continue;
}
// 其余行的规律是两种计算方式交替,因此用布尔量flag保证交替执行
if(flag) {
flag = false;
sb.append(s.charAt(i+j));
j += (numRows - 1 - i) * 2;
} else {
flag = true;
sb.append(s.charAt(i+j));
j += i * 2;
}
}
}
return sb.toString();
}
}
注意点
- 此题很明显是寻找数学规律的