前言
算法最难不过数学的抽象形式,但是能找到问题中的数学规律,那么问题也会变得简单起来,通过Z 字变形练习规律–周期。
一、Z 字变形
二、周期
package everyday;
// Z 字形变换。
public class Convert {
/*
target:讲字符串按Z字排列,水平组合字符形成新的字符串。
Z 字拉多长取决于numRows,所以每行字母在原本字符串的index由numRows决定。
以一个勾为周期,来看每行字符在字符串s中的index
第一行字符在何处?0 | 0 + numRows * 2 - 2 == 0 + (numRows - 1) * 2 | ... 注:一个周期只有一个值。
第二行字符在何处?1 | 1 + (numRows - i - 1) * 2 注:第二行至倒是第二行每个周期都有两个值。
第numRows行字符在何处?numRows - 1 | (numRows - 1) + (numRows - 1) * 2 | ...
*/
public String convert(String s, int numRows) {
if (numRows == 1) return s;
// 每个勾的周期:(numRows - 1) * 2
// 每个勾中双字符分别为i 和 i + (numRows - i - 1) * 2
StringBuilder sb = new StringBuilder();
// 第一行
for (int i = 0; i < s.length(); i += (numRows - 1) * 2) sb.append(s.charAt(i));
// 第二行至倒是第二行
for (int i = 1; i < numRows - 1; i++) {
for (int j = i; j < s.length(); j += (numRows - 1) * 2) {
// 第一个字符
sb.append(s.charAt(j));
// 周期中第二个字符
int next = j + (numRows - i - 1) * 2;
// 每个index都必须校验其是否越界。
if (next < s.length()) sb.append(s.charAt(next));
}
}
// 最后一行
for (int i = numRows - 1; i < s.length(); i += (numRows - 1) * 2) sb.append(s.charAt(i));
return sb.toString();
}
}
总结
1)算法找数学规律之一 -> 周期。
参考文献
[1] LeetCode Z 字变形