将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。
方法一
分析:
斜线上的元素在原字符串中的下标为j+size-2*i。
string convert(string s, int numRows) {
//如果numRows=1,结果就是s
if(numRows<=1) return s;
string res;
int size=2*numRows-2,n=s.size();
//i表示行号,也是每行开头元素的下标
for(int i=0;i<numRows;++i)
//遍历每一行
for(int j=i;j<n;j+=size){
res+=s[j];
if(i!=0&&i!=numRows-1&&j+size-2*i<n)
res+=s[j+size-2*i];
}
return res;
}
方法二
分析:
也可以用下面这种更直接的方法来做,建立一个大小为 numRows 的字符串数组,为的就是把之字形的数组整个存进去,然后再把每一行的字符拼接起来,就是想要的结果了。顺序就是按列进行遍历,首先前 numRows 个字符就是按顺序存在每行的第一个位置,然后就是 ‘之’ 字形的连接位置了,可以发现其实都是在行数区间 [1, numRows-2] 内,只要按顺序去取字符就可以了,最后把每行都拼接起来即为所求。
string convert(string s, int numRows) {
if(numRows<=1) return s;
string res;
vector<string> v(numRows);
int n=s.size(),i=0;
while(i<n){
//向下遍历numRows个字符
for(int pos=0;pos<numRows&&i<n;pos++){
v[pos]+=s[i++];
}
//斜向上遍历numRows-2个字符
for(int pos=numRows-2;pos>0&&i<n;pos--){
v[pos]+=s[i++];
}
}
for(auto s:v) res+=s;
return res;
}