将字符串 "PAYPALISHIRING" 以Z字形排列成给定的行数:
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
这个题就是一个简单的模拟题,给定一个字符串,按照给定的行数对字符串进行Z字形重排序。假设有一个二维数组,行数为给定值,
1、将字符串先按纵向填充,
2、到尾行以后再横向填充,
3、到首行再重复以上过程。
由此我们很容易就写出以下实现:
public String convert(String s, int numRows) {
if (s.length() == 0){
return "";
}
if (numRows == 1){
return s;
}
char[][] zMap = new char[numRows][s.length()];
int col = 0;
int row = 0;
//移动方向 true表示纵向移动 false表示横向移动
boolean direction = true;
int pos = 0;
while (pos < s.length()) {
if (direction) {
//纵向移动
zMap[row][col] = s.charAt(pos);
++row;
if (row >= numRows) {
//移动到最后一行后改为横向移动 切回纵向向上回退一行
direction = false;
--row;
}
} else {
//横向移动
--row;
++col;
zMap[row][col] = s.charAt(pos);
if (row <= 0) {
//纵向坐标到达首行后改为纵向移动 纵向想下移动一行
direction = true;
++row;
}
}
pos++;
}
StringBuilder rs = new StringBuilder();
for (int i = 0; i < numRows; ++i) {
for (int j = 0; j <= col; ++j) {
if (zMap[i][j] != '\0') {
rs.append(zMap[i][j]);
}
}
}
return rs.toString();
}
我们生成二维数组的过程为O(n),但是最后我们需要遍历一遍二维数组,导致复杂度变成了O(n^2),因此我们可以对此过程进行优化。二维数组我们实际上只用了一部分,中间为空字符的是没用的,最后访问的时候实际上是将二维数组的几行进行了拼接,因此在开始我们就可以直接使用numRows个字符串来存储二维数组的每行,最后对字符串进行拼接即可,复杂度变为O(n)。
改写如下:
public String convert2(String s, int numRows) {
if (s.length() == 0){
return "";
}
if (numRows == 1){
return s;
}
StringBuilder[] strs = new StringBuilder[numRows];
for (int i = 0; i < strs.length; i++) {
strs[i] = new StringBuilder();
}
int row = 0;
//移动方向 true表示纵向移动 false表示横向移动
boolean direction = true;
int pos = 0;
while (pos < s.length()) {
if (direction) {
//纵向移动
strs[row].append(s.charAt(pos));
++row;
if (row >= numRows) {
//移动到最后一行后改为横向移动 切回纵向向上回退一行
direction = false;
--row;
}
} else {
//横向移动
--row;
strs[row].append(s.charAt(pos));
if (row <= 0) {
//纵向坐标到达首行后改为纵向移动 纵向想下移动一行
direction = true;
++row;
}
}
pos++;
}
StringBuilder rs = new StringBuilder();
for (int i = 0; i < numRows; ++i) {
rs.append(strs[i]);
}
return rs.toString();
}