携手创作,共同成长!这是我参与「掘金日新计划 · 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();
}