6. Z 字形变换

时间:2022-4-15    作者:老大夫    分类: 力扣


题目地址: https://leetcode-cn.com/problems/zigzag-conversion/

题目要求:

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

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

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

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

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

string convert(string s, int numRows);

示例 1:

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

示例 2:

输入:s = "PAYPALISHIRING", numRows = 4
输出:"PINALSIGYAHRPI"
解释:
P     I    N
A   L S  I G
Y A   H R
P     I

示例 3:

输入:s = "A", numRows = 1
输出:"A"

提示:

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

代码

class Solution {
    public String convert(String s, int numRows) {
        //不用计算的情况
        if(s.length()==0||numRows==1){
            return s;
        }
        //定义列的数目,最多也就字符串那么长(一行的情况)
        int cols = s.length();
        //建立二维数组
        char[][] chars = new char[numRows][cols];
        //遍历字符串
        int r = 0;        //行和列都从0开始
        int c = 0;        //
        int i = 0;        //字符串的索引下标
        int bk = -1;       //结束遍历的标志
        while (true) {
            while (r < numRows) {
                chars[r][c] = s.charAt(i);
                i++;
                if (i >= s.length() || bk == 1) {
                    bk = 1;
                    break;
                }
                r++;
            }
            //跳出全部循环条件
            if (bk == 1) {
                break;
            }
            r--;                    //r已经到了 numRows,但是已经越界了,所以先-1到最底的行数
            while (r > 0) {
                r--;                //因为行已经到了最低部,所以要先减行
                c++;                //因为减行的同时,列也要增加
                chars[r][c] = s.charAt(i);
                i++;
                if(r==0){           //一会儿进入r<numRows循环时,r==0还会给r=0行赋值一次
                    i--;            //所以i不要增加,继续给r=0行赋值一次
                }
                if (i >= s.length() || bk == 1) {
                    bk = 1;
                    break;
                }
            }
            //跳出全部循环条件
            if (bk == 1) {
                break;
            }
        }
        //按行遍历二位数组,输出存入其中的字符
        StringBuilder sb=new StringBuilder();
        for(int x=0;x<numRows;x++){
            for (int y=0;y<cols;y++){
                if(chars[x][y]!=0)
                    sb.append(chars[x][y]);
            }
        }
        return sb.toString();
    }
}

思路

总共分为两大部分:1.按Z字形排列字符串,2:按每行提取出字符串
总体上按顺序遍历字符串每个字符
建立二维字符数组存放字符,没放入字符的位置 ascII码为0
给二位数组设定边界 :
1. 向下排列一列的规则是 r<numRows
2. 到了行边界后 行-- ,列++
放置字符后,按每行的顺序遍历输出字符

难点

1. 行边界的条件
2. 走"竖线"和走"斜线"的规则问题
3. 提取字符时如何判断是否是放入字符的位置

解决方法

  1. numRows就是行边界,到达此位置"竖线"遍历模式结束
  2. 使用两个while循环,一个放"竖线"遍历模式,一个放"斜线"遍历模式,每存入一个字符字符串索引向下走一位,不受"竖线"或"斜线"模式的影响
  3. 没存入字符的位置,ascII码是0

标签: 二维数组

版权所有:伸手党盘
文章标题:6. Z 字形变换
文章链接:https://ssdpan.cn/?post=70
本站文章来源于网络搜集和原创,仅供学习使用,未经授权请勿用于任何商业用途,如有侵权及时联系删除

推荐阅读:


扫描二维码,在手机上阅读