一. 题目描述:
1.基本要求
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
2.数据形式
- 输入
给出初始字符串string s,和需要变换成为的行数numRows - 输出
以从左往右的形式读,形成新的字符串
二. 思路简析
1.模拟排列
- 概述:
z型即s形(在排列完成后从左向右读取时二者无差别)。通过对于原字符串的顺序读取,每numRows个字符进行分段,对于每段中的字符进行分类(将其分别归类增添到n行)。新的字符串可以依据原字符串每个字符的分类总和生成。 - 具体实现思路:
- 对于原字符串的字符在模拟排列中的位置使用多个(numRows个)字符串进行记录
- 使用一个指针上到下再从下到上进行扫描,便于填充每一行的字符
- 第n个定长字符串记录的是模拟排列中第n行的字符
- 遍历一次生成模拟排列,将上述字符串的内容填充完毕,并将字符串合并成为新字符串
- 具体代码实现
class Solution {
public:
string convert(string s, int numRows) {
//如果是空字符返回空字符
//其实不用判断是否在z的边上的横或者中间的斜线,因为其对字符的读取顺序无影响
string curCol[numRows];
string result;
int len = s.length();
if(numRows == 1){
return s;
}//此时无法排成z字形,直接返回
int colptr = 0;//用于标志当前添加字符的行,由0到numRows-1再到0
bool isGoingUp = false;//标志colptr增加或者减少,增加为false
for(int i = 0; i < len; i++){
curCol[colptr] = curCol[colptr] + s[i];//将当前字符添加到第colptr行
if(colptr == 0){//指针指向最上方的行
if(isGoingUp){//在上升过程中
isGoingUp = false;
}//应当换方向
}else if(colptr == numRows-1){//指针指向最下方的行
if(!isGoingUp){//在下降过程中
isGoingUp = true;
}//应当换方向
}
if(isGoingUp){
colptr--;//向上移动指针
} else {
colptr++;//向下移动指针
}
}
for(int i = 0; i < numRows ;i++){
result = result + curCol[i];
}//将所有行合并为最终结果
return result;
}
};