一、题目描述
二、解题思路
- 首先,定义一个矩阵,这个矩阵保存每个像素
- 需要知道矩阵的行列,行就是传入的参数了,没什么可说的,关键是怎么求出列的数值
- 以
numRows = 3
为例,观察发现,当列的值为0、2、4、6…时,该列就全满 - 以
numRows = 5
为例,观察发现,当列的值为0、4、8、12…时,该列就全满 - 设当前列值为
column
,可以看出规律为当column % (numRows - 1) == 0
时,该列全满 - 移动当前字符的下标
i
- 如果当前列是满列,则
i
在本次操作中应该移动一列的长度- 这里要注意,每次循环还有
i++
的过程,为了保证每次操作正好移动一列的长度,i
加的是numRows - 1
而不是numRows
- 只有这样,才能利用每次循环额外的
i++
保证移动长度准确
- 这里要注意,每次循环还有
- 不是满列直接
i++
即可
- 如果当前列是满列,则
- 以
- 确定行列大小后,定义数组并初始化为
'\0'
- 像素“上色”
- 如果此列应为满列,那么用循环将该列填满
- 不为满列,就应该确定在该列中的那个唯一的像素点在哪一行,该行为
(numRows - 1) - (col % (numRows - 1))
(numRows - 1)
:是每行最后一个元素的下标- 观察发现,应该上色的像素所在行的下标要比最后一行的下标上偏一个位移,这个位移的大小,就是该列相对于前一个满列偏移的大小
(col % (numRows - 1))
三、解题代码
class Solution {
public:
string convert(string s, int numRows) {
string sln;
auto len = s.size();
if(!len) return sln;
if(len == 1 || numRows <= 1) return s;
int column = 0;
for(int i = 0; i < len; i++){
if(column % (numRows - 1) == 0)
i += (numRows - 1); //一定要减1,后面再来一个i++,每次循环正好是加上numRows
column++;
}
size_t cur = 0;
char Arr[numRows][column];
for(int row = 0; row < numRows; row++)
for(int col = 0; col < column; col++)
Arr[row][col] = '\0';
for(int col = 0; col < column && cur < len; col++)
if(col % (numRows - 1) == 0)
for(int row = 0; row < numRows && cur < len; row++)
Arr[row][col] = s[cur++];
else
Arr[(numRows - 1) - (col % (numRows - 1))][col] = s[cur++];
cur = 0;
for(int row = 0; row < numRows && cur < len; row++)
for(int col = 0; col < column; col++)
if(Arr[row][col])
sln += Arr[row][col];
return sln;
}
};
四、运行结果
注意几个测试点
- 传入的串为空:返回空串
- 传入的串长度为1:返回原串
- 传入的
numRows
小于0:返回原串 - 传入的
numRows
等于1:返回原串 - 传入的
numRows
大于串长度:写第一列像素的时候不要对串越界访问