题目:
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
输入:s = "PAYPALISHIRING", numRows = 3
输出:"PAHNAPLSIIGYIR"
示例 2:
输入:s = "PAYPALISHIRING", numRows = 4
输出:"PINALSIGYAHRPI"
解释:
示例 3:
输入:s = "A", numRows = 1 输出:"A"
题解
方法一
-
解题思路:
遍历字符串,将字符一一填入每一行,我们用数组arr记录每一行已经填入的数据 以s = "PAYPALISHIRING", numRows = 3为列:
步骤1. 第1次循环,第1个字符填入第1行; i = 0; arr[0] = 'P'
步骤2. 第2次循环,第2个字符填入第2行; i = 1; arr[1] = 'A'
步骤3. 第3次循环,第3个字符填入第3行 i = 2; arr[2] = 'Y' (第numRows次)
步骤4. 第4次循环,第4个字符填入第2行 i = 3; arr[1] = 'AP'
步骤5. 第5次循环,第5个字符填入第2行 i = 4; arr[0] = 'PA'
......
以arr下标代表行数,用rows表示;arr[rows]为每行的排的字符串,不难发现
当rows = 0时,开始从上往下依次填写,rows递增;如上述步骤1、步骤2、步骤3
当rows = numRows - 1时,开始翻转,从下往上依次填写,rows递减;如上述步骤3、步骤4、步骤5
- 代码实现:
/**
* @param {string} s
* @param {number} numRows
* @return {string}
*/
var convert = function(s, numRows) {
const n = s.length;
if (numRows === 1 || numRows >= n) {
return s;
}
var arr = new Array(numRows).fill('')
var rows = 0, // 当前字符应该填写到第几行
flag = -1; // 往上还是往下
for (var i = 0; i < n; i++) {
arr[rows] += s.charAt(i);
// 每次等于0(第一次循环)或者numRows - 1(第numRows循环)都会反转
if (rows === 0 || rows === numRows - 1) {
flag = - flag;
}
rows += flag;
}
return arr.join('');
};
-
复杂度分析:
- 时间复杂度 O(n) :遍历一遍字符串
s; - 空间复杂度 O(n) :各行字符串共占用O(n)额外空间。
- 时间复杂度 O(n) :遍历一遍字符串