题目
6. Z 字形变换
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
示例 2:
输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:
L D R
E O E I I
E C I H N
T S G
解析:
R=3
P A H N
A P L S I I G
Y I R
1 5 9 13
2 4 6 8 10 12 14
3 7 11
R=4
P I N
A L S I G
Y A H R
P I
1 7 13
2 6 8 12 14
3 5 9 11
4 10
假设当前行数是r,总行数R,I(n)表示某行第n个字母在原字符串中的index,n从0开始:
当r=1,R时,I(n+1) = I(n)+2(R-1)
当1<r<R时,
I(n+1) = I(n)+2(R-r) n为偶数时,
I(n+1) = I(n)+2(r-1) n为奇数时。
代码:
public class code6 {
public static String convert(String s, int numRows) {
if (s == null || s.length() == 0 || numRows == 1 || numRows >= s.length()) {
return s;
}
StringBuilder sb = new StringBuilder();
for (int i = 1; i < s.length() + 1; i += 2 * (numRows - 1)) {
sb.append(s.charAt(i - 1));
}
for (int i = 2; i < numRows; i++) {
boolean k = true;
for (int j = i; j < s.length() + 1; j += (k) ? 2 * (numRows - i) : 2 * (i - 1), k = !k) {
sb.append(s.charAt(j - 1));
}
}
for (int i = numRows; i < s.length() + 1; i += 2 * (numRows - 1)) {
sb.append(s.charAt(i - 1));
}
return sb.toString();
}
public static void main(String[] args) {
String s1 = "LEETCODEISHIRING";
int numRows1 = 4;
String str1 = convert(s1, numRows1);
System.out.println(str1);
String s2 = "LEETCODEISHIRING";
int numRows2 = 3;
String str2 = convert(s2, numRows2);
System.out.println(str2);
}
}
参考:
- LeetCode第六题之Z字形变换
- Z 字形变换-题解一
- Z 字形变换-题解二
附:
- Java StringBuffer 和 StringBuilder 类
- StringBuilder用法小结
- 深入理解Java常用类-----StringBuilder
- Java集合–List
- Java—List的用法与实例详解
- JAVA集合 - list常用方法
- Java List类
- Java 列表