将一个给定字符串 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"
提示:
1 <= s.length <= 1000
s 由英文字母(小写和大写)、',' 和 '.' 组成
1 <= numRows <= 1000
自己写的:
class Solution {
public:
string convert(string s, int numRows) {
if(numRows ==1)
return s;
int M = numRows;
int G= 2*M-2;//由这些字符串组成一组
string str="";
int N=s.length()/G;
int grpnum = (M-2)*2;//同一行相隔最远距离
for(int i=0;i<M;i++)
{
for(int j=0;j<=N;j++)
{
if(i==0||i==(M-1))
{
if ((i+j*G)>=s.length())
break;
str+=s[i+j*G];
}
else
{
if ((i+j*G)>=s.length())
break;
str+=s[i+j*G];
if ((i+grpnum+j*G)>=s.length())
break;
str+=s[i+grpnum+j*G];
}
}
if(i>0)
grpnum=grpnum-2;
}
return str;
}
};
第二种方式
class Solution {
public:
string convert(string s, int numRows) {
if(numRows==1)
return s;
vector<string> rows(numRows);
int row =0;
bool down=false;//方向向上
for(int i=0;i<s.length();i++)
{
rows[row]+=s[i];//矩阵赋值
if(row==0 || row ==numRows-1) down=!down;//方向反向
row+=down?1:-1;//方向向下,+1,方向向上-1
}
string str="";
for(int i=0;i<numRows;i++) str+=rows[i];
return str;
}
};
示例模板:通第一种方法类似
class Solution {
public:
string convert(string s, int numRows) {
if (numRows == 1) {
return s;
}
string res = s.substr(0, 1);
int k = 0;
int left = 0;//如果不是第一行和最后一行,其他行可以设置left和right
int right = 0;
for (int j = 0; j < numRows; j++) {
k = 0;
while (1) {
left = 2 * k * (numRows - 1) - j;
if (left >= s.size() && left > 0) {
// left=-1的时候,满足left>s.size(),即-1>14是成立的,难以理解
break;
}
else if (left >= 0 && left != right) {
res += s[left];
}
right = 2 * k * (numRows - 1) + j;
if (right >= s.size()) {
break;
}
else {
if (left != right) {
res += s[right];
}
}
k++;
}
}
return res;
}
};