Z字型变换
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。
示例 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
题解:
按行排序:
1.如果numRows = 1 直接返回s。
2.如果当前行row = 0 下一次向下一行加入字符,如果当前行row = numRows - 1下一次向上一行加入字符 。
3.按行拼接字符串。
// 按行排序
public String convert(String s, int numRows) {
if(numRows == 1)
return s;
ArrayList<StringBuffer> list = new ArrayList<>();
for (int i = 0; i < Math.min(s.length(), numRows); i++){
list.add(new StringBuffer());
}
int row = 0;
Boolean down = false;
char[] C = s.toCharArray();
for (char c : C){
list.get(row).append(c);
if (row == 0 || row == numRows - 1) // 当行为0向下走加1,为numRows-1时向上走减1
down = !down;
row += down ? 1 : -1;
}
StringBuffer stringBuffer = new StringBuffer();
for (StringBuffer s1 : list)
stringBuffer.append(s1);
return stringBuffer.toString();
}
按行访问:1.行 0中的字符位于索引 k (2 * numRows - 2) 处;
2.行numRows−1 中的字符位于索引 k (2 *numRows}- 2) + numRows- 1处;
3.内部的行 i 中的字符位于索引 k k(2⋅numRows−2)+i 以及 (k+1)(2⋅numRows−2)−i 处。
根据上面的规律访问字符串并拼接成新的字符串。
// 按行访问
public String convert1(String s, int nuwRows){
if(nuwRows == 1)
return s;
StringBuffer stringBuffer = new StringBuffer();
int temp = 2 * nuwRows - 2, n = s.length();
char[] C = s.toCharArray();
for (int i = 0; i < nuwRows; i++){
for (int j = 0; j + i < n; j += temp){
stringBuffer.append(C[j + i]); // i = 0时加入0行字符;
// i = numRows - 1时加入改行字符
if (i != 0 && i != nuwRows - 1 && j + temp - i < n)
stringBuffer.append(C[j + temp - i]); // 在i行加入对应的字符
}
}
return stringBuffer.toString();
}