- ⬇↗⬇字形变换:
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 ⬇↗⬇ 字形排列。
比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:
P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。
示例 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”
代码:
class Solution {
public static void main(String[] args) {
System.out.println(convert("ABC", 2));
}
public static String convert(String s, int numRows) {
/**
* 思路: 1、逐行从左到右计算下一个竖列的索引
* 2、下一字符索引大于字符串最大索引时当前行计算结束
* 3、每个相邻竖列之间需要计算一次中间字符(首尾行中间字符是相邻竖列字符本身)
*/
StringBuilder sb = new StringBuilder();
int len = s.length();
//边界条件
if (len <= numRows || len < 2 || numRows < 2) {
return s;
}
//最大偏移量(相邻两个列之间)
int maxRange = (numRows - 1) * 2;
//遍历行数
for (int i = 1; i <= numRows; i++) {
sb.append(s.charAt(i - 1));
//每行的第一个字符索引
int currentIndex = i - 1;
//左列字符距离下一字符的长度
int nextIndexLen = (numRows - i) * 2;
while(currentIndex < len - 1){
//下一字符索引
int nextIndex = currentIndex + nextIndexLen;
//索引越界,结束
if (nextIndex > len - 1) {
break;
}
//非首尾行时,相邻两列字符之间有字符
if (nextIndexLen > 0) {
sb.append(s.charAt(nextIndex));
}
//找下一列的字符索引
currentIndex = nextIndex + maxRange - nextIndexLen;
if (currentIndex > len - 1) {
break;
}
//非首尾行时,相邻两列字符之间有字符
if (nextIndexLen < maxRange) {
sb.append(s.charAt(currentIndex));
}
}
}
return sb.toString();
}
}