1. 题目
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:
P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"
。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
2. 示例
示例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"
提示:
1 <= s.length <= 1000
s 由英文字母(小写和大写)、',' 和 '.' 组成
1 <= numRows <= 1000
3. 题解
这个题目存在潜在规律,我们只要把index和行号的关系找到就能按照一定顺序输出字符串了。
首先我们观察第一行,第j列第一个数和第j+1列第一个数之间,第j列第一个数所在列下面有numRows - 1个数,-1就是第一个数;第在斜对角线上,除去第j列最后一个元素,剩下numRows-1;总的数为(numRows-1) + (numRows-1) = 2 * numRows - 2。所以第一行的index为:i + k * (2 * numRows -2), i = 0。
观察第i行(0<i<numRows-1),发现除了有与第一行同样的规律,即i+ k * (2 * numRows - 2);中间还有一个数,它离第i行第j+1列数中间隔了2i个数,即i + k*(2*n - 2) - 2i = k*(2*numRows - 2) - i;
最后一行与第一行一样的。
4. 实现
public class Convert6 {
public String convert(String s, int numRows) {
if(numRows == 1) return s;
StringBuilder str = new StringBuilder();
int n = s.length();
int cycleLen = 2 * numRows - 2;
for(int i = 0; i < numRows; i++) {
for(int j = 0; j + i < n; j += cycleLen) {
str.append(s.charAt(j + i));
if(i != 0 && i != numRows - 1 && j + cycleLen - i < n) {
str.append(s.charAt(j + cycleLen - i));
}
}
}
return str.toString();
}
public static void main(String[] args) {
String str = "PAYPALISHIRING";
int numRows = 3;
System.out.println(new Convert6().convert(str, numRows));
}
}
5. 结语
努力去爱周围的每一个人,付出,不一定有收获,但是不付出就一定没有收获! 给街头卖艺的人零钱,不和深夜还在摆摊的小贩讨价还价。愿我的博客对你有所帮助(*^▽^*)(*^▽^*)!
如果客官喜欢小生的园子,记得关注小生哟,小生会持续更新(#^.^#)(#^.^#)。