
题目:
将一个给定字符串根据给定的行数,以从上往下、从左到右进行Z 字形排列。
输入: s = "LEETCODEISHIRING", numRows =4
输出:"LDREOEIIECIHNTSG"
解释:
L D R
E O E I I
E C I H N
T S G
算法:

解法:
方法一:把所有字符遍历放入数组中,对数组重新组合
public String convert(String s, int numRows) {
\t\tif(s.length() == 0){
return "";
}
\t\tif(numRows == 1){
\t\t\treturn s;
\t\t}
\t\tint h = s.length() / (numRows-1);
\t char[][] a = new char[numRows][h*(numRows-1)+1];
\t int n = 0;
\t for(int i=0;i\t \tif(i%(numRows-1) == 0){
\t\t \tfor(int j=0;j<numrows>\t\t \t\tif(n >= s.length()){
\t\t \t\t\tbreak;
\t\t \t\t}
\t\t \t\ta[j][i] = s.charAt(n);
\t\t \t\tn++;
\t\t \t}
\t \t}else{
\t \t\tif(n >= s.length()){
\t \t\t\tbreak;
\t \t\t}
\t \t\ta[numRows-1-i%(numRows-1)][i] = s.charAt(n);
\t \t\tn++;
\t \t}
\t }
\t char[] b = new char[s.length()];
\t int count = 0;
\t for(int i=0;i<numrows>\t \tSystem.out.println(String.valueOf(a[i]));
\t \tfor(int j=0;j\t \t\tif(a[i][j] != '\\0'){ /<numrows>/<numrows>
\t \t\t\tif(count >= s.length()){
\t \t\t\t\tbreak;
\t \t\t\t}
\t \t\t\tb[count] = a[i][j];
\t \t\t\tcount++;
\t \t\t}
\t \t}
\t }
\t
\t System.out.println(String.valueOf(b));
\t\treturn String.valueOf(b);
}
方法二:通过从左向右迭代字符串,我们可以轻松地确定字符位于 Z 字形图案中的哪一行。
String convert2(String s, int numRows) {
\t\t if (numRows == 1) return s;
\t List<stringbuilder> rows = new ArrayList<stringbuilder>();
\t for (int i = 0; i < Math.min(numRows, s.length()); i++)
\t rows.add(new StringBuilder());
\t int curRow = 0;
\t boolean goingDown = false;
\t for (char c : s.toCharArray()) {
\t rows.get(curRow).append(c);
\t if (curRow == 0 || curRow == numRows - 1) goingDown = !goingDown;
\t curRow += goingDown ? 1 : -1;
\t }
\t StringBuilder ret = new StringBuilder();
\t for (StringBuilder row : rows) ret.append(row);
\t return ret.toString();
\t}/<stringbuilder>/<stringbuilder>
方法三:每一行字母的所有下标其实是有规则的
我们先假定有 numRows=4 行来推导下,其中 2*numRows-2 = 6 , 我们可以假定为 step=2*numRows-2 ,我们先来推导下规则:
第0行: 0 - 6 - 12 - 18
==> 下标间距 6 - 6 - 6 ==> 下标间距 step - step - step
第1行: 1 - 5 - 7 - 11 - 13
==> 下标间距 4 - 2 - 4 - 2 ==> 下标间距step-2*1(行)-2*1(行)-step-2*1(行)-2*1(行)
第2行: 2 - 4 - 8 - 10 - 14
==> 下标间距 2 - 4 - 2 - 4 ==> 下标间距step-2*2(行)-2*2(行)-step-2*2(行)-2*2(行)
第3行:3 - 9 - 15 - 21
==> 下标间距间距 6 - 6 - 6 ==>下标间距step - step - step
可以得出以下结论:
起始下标都是行号
第0层和第numRows-1层的下标间距总是step 。
中间层的下标间距总是step-2*行数,2*行数交替。
下标不能超过len(s)-1
String convert1(String s, int numRows) {
\t\tif (numRows == 1) return s;
\t\tint step = numRows * 2 - 2; // 间距
\t\tint index = 0;// 记录s的下标
\t\tint len = s.length();
\t\tint add = 0; // 真实的间距
\t\tString ret = "";
\t\tfor (int i = 0; i < numRows; i++) // i表示行号
\t\t{
\t\t\tindex = i;
\t\t\tadd = i * 2;
\t\t\twhile (index < len)//超出字符串长度计算下一层
\t\t\t{
\t\t\t\tret += s.charAt(index); // 当前行的第一个字母
\t\t\t\tadd = step - add;// 第一次间距是step -2*i,第二次是2*i,
\t\t\t\tindex += (i == 0 || i == numRows-1) ? step : add; // 0行和最后一行使用step间距,其余使用add间距
\t\t\t}
\t\t}
\t\treturn ret;
\t}
閱讀更多 努力的椰子 的文章