题目
分析
原有的单行字符串,比如'abcdefg'
,要求摆放成3行,刚开始是由上向下摆放,
先处理第一个字符a
,放到第一行,得到:
a
再处理第二个字符b
,放到第二行,得到:
a
b
再处理第三个字符c
,放到第三行,得到:
a
b
c
此时,三行已经摆放完毕,该折返了,即由下到上摆放。
所以此时处理第四个字符d
,就要放到第二行上,得到:
a
b d
c
再继续处理第五个字符e
,放到第一行上,得到:
a e
b d
c
此时,第一行处理完,又要折行了,又变成从上向下摆放,
所以此时再处理第六个字符f
,就要放到第二行去,得到:
a e
b d f
c
以此类推。
经过上面的分析,可以知道所涉及到的变量有如下几个:
- 原字符串 s
- 题目指定行数 numRows
- 当前正在摆放的行数 row
- 控制方向 flag 。
- 摆放后得到的每一行的字符串结果
- 最终得到的字符串
思路
把分析过程连贯起来,就是,
-
我们需要根据原字符串和指定行数,对字符串进行遍历,来摆放字符。
-
我们需要创建一个初始化数组,数组的每个元素都是一个空字符串,
分别表示摆放后的每一行字符串结果。
字符摆放到了第一行,就把这个字符添加到数组的第一个元素中,以此类推。
- 摆放时,实时更新正在摆放的行数。
如果是由上到下摆放,行数就是递增的。
即在第一行摆放了一个字符后,就要去第二行摆放第二个字符了。
如果是由下到上,行数就是递减的。
即在第三行摆放了一个字符后,就要去第二行摆放字符了。
- 要实时监测是否需要折行
比如题目要求摆放3行,那么在第三行摆放了字符后,就要折行,去第二行摆放。
另外,如果原字符串的字符个数不超过行数或者行数为1行,那么直接返回原字符串
解题
/*
* s 原字符串
* numRows 题目要求的行数
*/
const convert = function(s, numRows) {
// 如果原字符串的字符个数不超过行数或者行数为1行,那么直接返回原字符串
if(numRows === 1 || s.length <= numRows) {
return s
}
// 生成一个包含多个空字符串的数组,目的是得到多个初始字符串
let arr = new Array(numRows).fill('')
// 控制方向的变量flag ,为true表示上到下,为false表示下到上
let flag = true
// 定义当前正在处理的行数currentRow,从第1行开始
let currentRow = 1
// 遍历原字符串
for(let item of s) {
// 把摆放的字符放到对应行数的字符串中
arr[currentRow - 1] += item
// 遍历时根据当前进行的方向,实时更新当前处理的行数
flag ? currentRow++ : currentRow--
// 遍历时监测当前进行的方向
// 如果进行到了最后一行,就变成由下到上。
// 如果是进行到了第一行,就变成由上到下
if (currentRow === numRows) {
flag = false
} else if (currentRow === 1) {
flag = true
}
}
// 返回结果
return arr.join('')
}