力扣#6 Z字形变换 (难度:中等)

题目:

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

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

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

解题思路:

由于要将字符串s重新排列为多行字符串,所以选用List进行字符串存取。

1. 首先确定List集合的大小,当字符串s的长度小于numRows时,List的大小==s.length(),当s的长度大于等于numRows时,List的长度==numRows,所以得出List.size == Math.min(s.length(), numRows);

2. 我们用一个布尔变量direction记录当前字符串的遍历方向,true表示向下构造,false表示向斜上方构造,初始设置为false。并且我们用一个整型变量记录当前遍历行数。

3. 下来我们模拟Z字形字符串的构造过程:每次遍历首先将当前遍历字符append到当前行字符串后边。其次更新当前方向,如果当前行为0,direction由false反转为true,如果当前行为numRows - 1,direction由true反转为false。最后通过direction更新当前行,direction为true,行数加1,direction为false,行数减1。

4. 遍历结束后,将所有字符串按照从上到下的顺序组合起来即为答案。

注意:

如果numRows为1,应直接返回字符串s。否则,在遍历到第二行时,会出现空指针异常。

代码示例:

public class Convert {
    public String convert(String s, int numRows) {
        if (numRows == 1) return s;
        List lists = new ArrayList<>();
        for (int i = 0; i < Math.min(s.length(), numRows); i++) {
            lists.add(new StringBuilder());
        }
        boolean direction = false;
        int curRow = 0;
        for (char c : s.toCharArray()) {
            lists.get(curRow).append(c);
            if (curRow == 0 || curRow == numRows - 1) direction = !direction;
            curRow += direction ? 1 : -1;
        }
        StringBuilder str = new StringBuilder();
        for (StringBuilder sb : lists)
            str.append(sb);
        return str.toString();
    }
}

 

你可能感兴趣的:(模拟,leetcode,数据结构,java,字符串)