LeetCode6.Z字形变换 详解

LeetCode6.Z字形变换

题目描述

/**
     * 将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
     * 比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:
     *
     * P   A   H   N
     * A P L S I I G
     * Y   I   R
     * 之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。
     * 请你实现这个将字符串进行指定行数变换的函数:
     */

思路分析

 //思路分析:
    //1. 先确定这个字符串展开后的最少行数,原则上是numRows,
    //   但是如果s.length < numRows,那么展开是最少行数应该为 s.length
    //2. 确定好展开的行数后,考虑这些字符在每行如何存储,可以考虑使用字符串长度可变的StringBuffer来存储每一行
    //   然后将每一行的StringBuffer存放在一个List集合中
    //3. 考虑这些字符如何Z字形存储的问题,因为最后要打印按行存储的字符串,所以在存储字符的时候不用考虑存储后的形状,
    //   只需要将字符存入指定的行即可
    //4. 定义两个指针 curRow指向当前行,direct 表示添加字符的方向,
    //   假定direct = true表示向下添加字符,direct = false,表示向上添加字符,
    //   当direct指向第一行或者最后一行时,改变方向
    //5. 字符添加完毕后,遍历集合中的StringBuffer即可
	//6. 详解见源码

源码及分析

/**
     * @param s       给定的字符串S
     * @param numRows 给定的字符串按照多少行进行Z字形展开
     * @return
     */
    public String convert(String s, int numRows) {
        //先进行数据校验
        if (numRows == 1) {
            return s;
        }

        //拿到Z自行变换的行数
        int min = Math.min(s.length(), numRows);
        //总共有min行,第一行索引为0,最后一行索引为 min - 1

        //创建存储StringBuffer的集合
        ArrayList<StringBuffer> list = new ArrayList<>();

        //向每行添加一个StringBuffer容器
        for (int i = 0; i < min; i++) {
            list.add(new StringBuffer());
        }

        //定义两个指针curRow和direct
        //默认刚开始在第一行,往下走
        int curRow = 0;
        boolean direct = true;

        //遍历字符串的字符,向指定位置添加字符
        for (char c : s.toCharArray()) {

            //如果向下添加
            if (direct) {
                //向当前可变字符串中添加字符
                list.get(curRow).append(c);
                //每添加依次,当前行+1
                curRow++;
                //判断是否到达最后一行
                if (curRow == min) {
                    //如果到达最后一行,改变direct的方向,重置当前行curRow
                    direct = false;
                    curRow -= 2;
                }
            } else {
                //向下添加
                list.get(curRow).append(c);
                //每添加一个字符,当前行-1
                curRow--;
                //判断是否到达第一行
                if (curRow == -1) {
                    //如果到达第一行,改变方向,重置当前行
                    direct = true;
                    curRow += 2;
                }
            }
        }
        //循环结束后所有的字符已经按z自行变换添加完毕
        //拿到字符串返回即可
        StringBuffer stringBuffer = new StringBuffer();
        for (StringBuffer buffer : list) {
            //字符串拼接
            stringBuffer = stringBuffer.append(buffer);
        }
        //测试
        //stringBuffer = list.get(1);
        return new String(stringBuffer);
    }

上一篇:020_Mybatis配置解析


下一篇:俄罗斯方块