leetcode刷题日记-【6. Z 字形变换】

88 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第12天,点击查看活动详情

题目描述

将一个给定字符串 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

题目元素

  • 字符串s代表原始字符串
  • numRows代表需要将s内的字符按照numRows行,从最左边开始-从上往下-从下往上依次重复的顺序书写字符numRows行,形成新的字符串数组。然后再按照从左往右-从上到下的顺序读取这个新数组,得到的字符串就是新的字符串。

解题思路

首先确定存储结构,按照题目元素,需要存储新的字符排列方式,涉及到两个维度,所以这里应该用二维数组来存储新的字符排序。

第一维数组代表纵向的字符数组,第二维数组代表在这个纵向位置的横向数组。 也可以把二维数组看成一个x、y坐标轴上的所有点。将字符串s按照要求放置进这个二维数组,然后再遍历这个二维数组获得新的字符串。

举例:

  • s='PAYPALISHIRING';
  • numRows = 4;
  • 二维数组int[][] res = new res[numRows][s.length()];

这里注意第一维数组的length应该是numRows,因为第一维数组是代表行数;但是每一行的数组元素并不固定,所以这里直接取s的长度。

  • 从上往下 res[0][0]='p';res[1][0]='A';res[2][0]='Y';res[3][0]='P';
  • 从下往上 res[2][1]='A';res[1][1]='L';res[0][1]='I';
  • 从上往下 res[1][2]='S';res[2][2]='H';res[3][1]='I';
  • 从下往上 res[2][3]='R';res[1][3]='I';res[0][2]='N';
  • 从上往下 res[1][4]='G';

遍历二维数组: newS='PINALSIGYAHRPI';

代码实现

public static String convert(String s, int numRows) {
     // 只有一行直接返回s
    if (numRows == 1){
        return s;
    }
    // 创建二维数组
    char[][] newArr = new char[numRows][s.length()];
    char[] chars = s.toCharArray();
    // 遍历字符串s,按照顺序放入二维数组中
    int top = 0;
    // 记录当前操作是否是从上往下的操作
    boolean frontTop = true;
    // 每一行对应的具体数组下标
    Map<Integer, Integer> rowAndIndexMap = new HashMap<>();
    for (int i = 0; i < chars.length ; i ++) {
        Integer index = rowAndIndexMap.get(top);
        if (index == null) {
            index = 0;
        }else  {
            index ++;
        }
        // 当前行数的下标向后移一位
        rowAndIndexMap.put(top,index);
        // 设置二维数组的值
        newArr[top][index] = chars[i];
        if (frontTop){
            // 从上往下的
            if (top == numRows-1){
                --top;
                frontTop = false;
            }else {
                ++top;
            }
        }else {
            // 从下往上的
            if (top == 0){
                ++top;
                frontTop = true;
            }else {
                --top;
            }
        }
    }
    // 获取到二维数组之后对数组的字符进行拼接
    StringBuilder res = new StringBuilder();
    for (int i =0; i < numRows; i ++){
        char[] firstArr = newArr[i];
        Integer index = rowAndIndexMap.get(i);
        if (index != null){
            for (int j = 0; j <= index;j ++){
                res.append(firstArr[j]);
            }
        }
    }
    return res.toString();
}