题目描述
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例
- 示例 1:
输入:s = “PAYPALISHIRING”, numRows = 3
输出:“PAHNAPLSIIGYIR”
-
示例 2:
-
示例 3:
输入:s = “A”, numRows = 1
输出:“A”
提示:
- 1 <= s.length <= 1000
- s 由英文字母(小写和大写)、‘,’ 和 ‘.’ 组成
- 1 <= numRows <= 1000
解题思路
- 应该可以使用数学方法解题,即推导出各个字符的位置,运用逻辑判断使用不同的计算公式,但是我没有使用这种方法。
- 使用二维数组辅助存储,计算过程结束后,遍历数组,取出要返回的字符串;
- 首先先定义好合适大小的数组;
- 分析字符的分布规律
先将题目给出的示例二维数组分布沿二四象限做翻转,可以很直接的看出分布规律:
a. 首先向右正常填充;
b. 当到达最右边界时,向左填充,此时每向左填充一个字符,同时向下移动一行;
- 得到填充完后二维数组,将要返回的字符串取出并返回。
代码
class Solution {
public:
string convert(string s, int numRows) {
int s_len = s.length();
if(s_len == 1) return s; // 数组长度为一,直接返回
if(numRows == 1) return s; // 给定行数为一,也直接返回
// 确定二维数组的行和列
int col = numRows;
// int row = s_len / (3 * numRows - 2) * numRows + numRows; // 此时会发生内存越界
int row = s_len; // 这个不会,还是没想清楚原因
// 初始化二维数组,也可以定义为 char 数组,更节省内存
int **arr;
arr = new int*[row];
int i = 0;
for(i = 0; i < row; i++){
arr[i] = new int[col];
memset(arr[i], 0, sizeof(int) * col);
}
// cout << "s_len = " << s_len << endl;
// cout << "row = " << row << ", col = " << col << endl;
int index = 0;
int col_ = 0;
int row_ = 0;
int right = 1; // 初始方向,向右填充
while(index < s_len){
// 向右填充
if(right && col_ < col){
// if(index > 100)
// cout << row_ << ":" << col_ << ":" << index << " ";
arr[row_][col_++] = s[index++];
}else if(right){ // 当向右填充到边界时,改变方向
right = 0; // right = 0,表示向左;= 1 表示向右
row_++;
col_ -= 2;
}
// 向左填充
if(!right && col_ >= 0){
// if(index > 100)
// cout << row_ << ":" << col_ << ":" << index << " ";
arr[row_++][col_--] = s[index++];
}else if(!right){ // 变向
right = 1;
row_--;
col_ += 2;
}
}
string ret = "";
int j = 0;
// 注意遍历的起始位置以及方向
for(i = 0; i < col; i++){
for(j = 0; j < row; j++){
if(arr[j][i] != 0){ // 对应位置不为 '0',即取出
ret += arr[j][i];
}
}
}
// for(i = 0; i < row; i++){
// for(j = 0; j < col; j++){
// printf("%c ", arr[i][j]);
// }
// cout << endl;
// }
return ret;
}
};
提交结果
总结
明明是简简单单的逻辑小游戏,但是直接用了 暴力模拟 的方法解决,耗时和内存感人。