题目

6. Z 字形变换

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:

L   C   I   R
E T O E S I I G
E   D   H   N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);
示例 1:

输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"

示例 2:

输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:

L     D     R
E   O E   I I
E C   I H   N
T     S     G

解析:

R=3

P   A   H   N
A P L S I I G
Y   I   R

1   5   9     13
2 4 6 8 10 12 14
3   7   11


R=4

P     I     N
A   L S   I G
Y A   H R
P     I  

1     7       13
2   6 8    12 14
3 5   9 11
4     10
假设当前行数是r,总行数R,I(n)表示某行第n个字母在原字符串中的index,n从0开始:
当r=1,R时,I(n+1) = I(n)+2(R-1)1<r<R时,
I(n+1) = I(n)+2(R-r) n为偶数时,
I(n+1) = I(n)+2(r-1) n为奇数时。

代码:

public class code6 {
    public static String convert(String s, int numRows) {

        if (s == null || s.length() == 0 || numRows == 1 || numRows >= s.length()) {
            return s;
        }

        StringBuilder sb = new StringBuilder();

        //i表示当前行号
        for (int i = 1; i < s.length() + 1; i += 2 * (numRows - 1)) {
            sb.append(s.charAt(i - 1));
        }

        for (int i = 2; i < numRows; i++) {
            boolean k = true;
            for (int j = i; j < s.length() + 1; j += (k) ? 2 * (numRows - i) : 2 * (i - 1), k = !k) {
                sb.append(s.charAt(j - 1));
            }
        }

        for (int i = numRows; i < s.length() + 1; i += 2 * (numRows - 1)) {
            sb.append(s.charAt(i - 1));
        }

        return sb.toString();
    }

    public static void main(String[] args) {
        String s1 = "LEETCODEISHIRING";
        int numRows1 = 4;
        String str1 = convert(s1, numRows1);
        System.out.println(str1);

        String s2 = "LEETCODEISHIRING";
        int numRows2 = 3;
        String str2 = convert(s2, numRows2);
        System.out.println(str2);

    }
}

参考:

  1. LeetCode第六题之Z字形变换
  2. Z 字形变换-题解一
  3. Z 字形变换-题解二

附:

  1. Java StringBuffer 和 StringBuilder 类
  2. StringBuilder用法小结
  3. 深入理解Java常用类-----StringBuilder
  4. Java集合–List
  5. Java—List的用法与实例详解
  6. JAVA集合 - list常用方法
  7. Java List类
  8. Java 列表