字符串,锯齿形转换
思路:
example :
String : “0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15” row:4
先把这一串字符串想象成一个 字符数组: char[] arr = {‘0’,‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,…}
0 6 12
1 5 7 11 13
2 4 8 10 14
3 9 15
先横向分析 : 不算 中间插入的数字 如 5,6,11,12 , 每一行数字的间隔就是 : 2 * row - 2 (如: 1 - 7)
先把这个间隔看成公式,把它记下来 : size = 2 * row - 2 = 6;
这样的话,设一个 参数i = 0,表示字符在数组里面的下标,可以算出每个字符在字符数组的位置的
如 : ‘0’= arr[i] , ‘6’ = arr[i+size] ‘12’ = arr[i+size+size]
#这 样的话,元素的位置就被解决了,还有一个问题就是中间插入的元素, 如 5,6,11,12等
认真发现的话,其实也是可以发现规律的, 先看 ‘5’的位置 , 已经知道’5’在数组中的下标为 5,这样可以反推
我们先前已经有两个元素之间的间隔 size 了, 那么 还可以设置一个参数 l 表示这个元素所在的行数, 如’0’‘6’'12’在第一行
l 就 设置为 0, 也是从 0 算起那么,'5’就在第 2行 , l 就是 1, 既然5 在1 和 7 之间插入的,那么可以先求出 '1 ‘和’5’
的 位置 ‘1’: arr[1] , 那么 他后面字符’7’的位置想都不用想 ‘7’: arr[1+size] = 7 , 那么就可以反推了
不知道规律没关系,我也不知道,但是可以先实验一下 ,知道 '5’的位置为 5
可以列一个方程了 : 5 = ? ,因为有前后元素的关系,所以可得 ‘5’ =arr[1 + size - 1-1];
可以化为 size + i - l * 2 如果不确定,可以用于其他插入的字符上,看看是不是这样
最后一条, 观察一下 插入字符的位置 ,是 除了 第 一 行 和 最后一行才有插入字符的,所以在添加字符的时候要避免第一行和最后一行
public static String convert(String s, int numRows) {
int len = s.length();
// 先判断不用锯齿转换的情况 PAYPALISHIRING
if(s == null || len <= 0)
return "";
if(len <= numRows || numRows == 1)
return s;
// 结果字符串
String result="";
int size = 2 * numRows - 2;
// 外层循环控制行,每行对每个字符逐一判断
for(int l = 0 ; l != numRows ; ++l) {
// 一行的一个字符到另一个字符之间的 距离应该每次 加 size
for(int i = l ; i < len ; i += size) {
result += s.charAt(i);
// 除了 第 一 行 和 最后一行才有插入字符的,所以在添加字符的时候要避免第一行和最后一行
if(l != 0 && l != numRows-1 && size + i - l * 2 < len) {
result += s.charAt(size + i - l * 2);
}
}
}
return result;
}