版权声明: https://blog.csdn.net/Dorothy_Xue/article/details/83004764
题目描述:
将字符串 "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
方法:
class Solution {
public:
string convert(string s, int numRows){
string str;
int numCols,inGroupNum,groupNum,res;
if(s.size()==0) return str="";//空串
if(numRows==1) return s;//输出一行
if(numRows==2){inGroupNum=2;}//输出两行,每组几个数
else inGroupNum=2*numRows-2;//多于两行
if(s.size()%inGroupNum==0) groupNum=s.size()/inGroupNum;
else groupNum=s.size()/inGroupNum+1;//有几组
int rest=s.size()-(groupNum-1)*inGroupNum;//最后一组几个数
if(rest<=numRows) res=1;//最后一组的数能分到几列
else res=rest-numRows+1;
numCols=inGroupNum*(groupNum-1)+res;//数组应分配的列数
char Z[numRows][numCols];
for(int i=0;i<numRows;i++)
for(int j=0;j<numCols;j++)
Z[i][j]=' ';//初始化
int row=0,col=0;
int flag=0;//记录遍历字符串
for(int i=0;i<groupNum;i++)//group数
{
for(int j=0;j<numRows;j++)//第一列
{
if(flag<s.size())
{
Z[row++][col]=s[flag++];
if(row>=numRows) row--;
}
else break;
}
for(int k=0;k<inGroupNum-numRows;k++)//第一列后的几列
{
if(flag<s.size())
Z[--row][++col]=s[flag++];
else break;
}
if(i<groupNum-1)//一个group的最后一列完成,回到首行。
{
row--;col++;
}
}
for(int i=0;i<numRows;i++)//顺序读取
for(int j=0;j<numCols;j++)
{
if(Z[i][j]!=' ')
str.push_back(Z[i][j]);
}
return str;
}
};
思路:
将Z字形字符串分割成group,如下图:
设一个字符数组用于接收排列成Z字形的字符,并计算好group数,每个group内有几个字符等信息,并且需要考虑空串,以及numRows为1和2的特殊情况。