题目描述:
将一个给定字符串 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"
解题思路:
看到题目的时候第一反应是通过二维组解题,取给定行数numRows作为二维数组行数,取字符串长度作为二维数组最大列数,通过观察可以找到按给定行数划分:
String arr[][] = new String[numRows][s.length()];
// 初始化数组默认值"-1"填充多余数组空间
for (int i = 0;i < numRows;i++){
for (int j = 0;j < s.length();j++){
arr[i][j] = "-1";
}
}
通过遍历字符串进行取值,例如:
输入 ABCDEFG 4
A -1 -1 G arr[0][0] arr[0][1] arr[0][2] arr[0][3]
B -1 F -1 arr[1][0] arr[1][1] arr[1][2] arr[1][3]
C E -1 -1 arr[2][0] arr[2][1] arr[2][2] arr[2][3]
D -1 -1 -1 arr[3][0] arr[3][1] arr[3][2] arr[3][3]
在通过字符串遍历取值赋值到二维数组的过程中观察到发现并不需要开辟二维数组空间,只需要开辟numRows个一维数组并对字符串进行遍历,需要注意每遍历完numRows次后需要倒置一维数组的顺序后在进行取值:
//输入 ABCDEFGH 4
//开辟4个一维数组空间:
arr[0] arr[1] arr[2] arr[3]
// 字符串进行Z字排序后
A G arr[0] = {"A","G"}
B F H arr[1] = {"B","F","G"}
C E arr[2] = {"C","E"}
D arr[3] = {"D"}
// 对字符串进行从左到右遍历并将遍历的结果存放至数组arr[0]至arr[3]中
// 插入数组的顺序为0->1->2->3->2->1->0->1
// 最后输出arr[0] + arr[1] + arr[2] + arr[3] 为Z字排序后字符串
代码实现:
public class ConvertZ {
public static void main(String[] args) {
convert("ABCDEFGHIJ",3);
}
public static String convert(String s, int numRows) {
// 当给定行数小于2或大于等于numRows时输出本身
if (numRows < 2 || numRows >= s.length()) return s;
int len = s.length();
// 数组倒置标志 数组起始位置
int flag = 1 , add = 0;
String str = "";
// 开辟一维数组空间
String [] arr = new String[numRows];
Arrays.fill(arr,"");
// 遍历字符串
for (char chr : s.toCharArray()){
arr[add] += chr;
// 当变量为0或numRows - 1时需要倒置数组进行遍历赋值
if (add == 0 || add == numRows - 1) flag = -flag;
add -= flag;
}
for (int j = 0;j < numRows;j++) str += arr[j];
return str;
}
}