#每日一题

N 字形变换

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

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

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。

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

示例 1:
输入:s = "PAYPALISHIRING", numRows = 3
输出:"PAHNAPLSIIGYIR"

示例 2:
输入:s = "A", numRows = 1
输出:"A"

提示:
1 <= s.length <= 1000
s 由英文字母(小写和大写)、',' 和 '.' 组成
1 <= numRows <= 1000

题解:

想象成一个二维数组,按照顺序把一个个单词放到二维数组对应位置上,然后再读取而为数组进行拼装,但是此处可以采用一个List<StringBuilder>进行放置。

一开始从第一行的第一列开始放,放到第一列的最后一行的时候反转方向,直到又放到了第一行的某一列,再反转方向,依次类推即可。

public String convert(String s, int numRows) {
        // 特殊情况特殊处理
        if (numRows < 2) return s;
        char[] chars = s.toCharArray();
        List<StringBuilder> lists = new ArrayList<>();
        // 此处采用stringbuilder集合
        for (int i = 0; i < numRows; i++) {
            lists.add(new StringBuilder());
        }
        // i标识集合中第几个stringbuiler也就是表示第几行
        // way表示此时是从上往下塞数据还是从下往上
        int i = 0,way = -1;
        for (char c : chars) {
            lists.get(i).append(c);
            // 当到第一列的最下面一个时,就可以理解为开始从下往上填充字符串,到第二列最上面时,又可以理解为又要从上往下填充字符串,出现这两种状况就将way变成相反的值
            if (i == 0 || i == numRows - 1) way = - way;
            i += way;
        }
        StringBuilder builder = new StringBuilder();
        for (StringBuilder b : lists) {
            builder.append(b);
        }
        return builder.toString();
    }