这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战
前言
关于 LeetCode 数组类型题目的相关解法,可见LeetCode 数组类型题目做前必看,分类别解法总结了题目,可以用来单项提高。觉得有帮助的话,记得多多点赞关注哦,感谢!
题目描述
将一个给定字符串 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"
链接:leetcode-cn.com/problems/zi…
题解
这道题题意是将一个字符串按照 z 字形排列,排列后按每行字符依次输出。做法就是模拟这个 z 字形的过程。
用一个数组 res 来表示转变后的字符串数组,res 每个元素为转变后每行对应的字符串,比如 res[0] 代表转变后第 0 行的字符串,对应题目的话,res[0] = 'PAHN', res[1] = 'APLSIIG', res[2] = 'YIR'。 初始时,每个字符串都为 '',我们需要将其填充。
如何填充呢?观察转变后的数组可以发现,当按照 z 字形遍历时,行号是从 0 递增到最大,然后再从最大递减到 0, 我们可以用一个方向变量来表示,当达到最大或者最小时,变换方向变量的正负。
具体实现如下,时间复杂度 O(n)
/**
* @param {string} s
* @param {number} numRows
* @return {string}
*/
var convert = function(s, numRows) {
if (numRows <= 1) return s
let res = new Array(numRows).fill('')
let indexDir = -1 // 方向变量
let index = 0
for (let i = 0; i < s.length; i++) {
res[index] += s[i]
// 转变方向
if (index === numRows -1 || index === 0) {
indexDir = -indexDir
}
index += indexDir
}
let ans = ''
for (let i = 0; i < numRows; i++) {
ans += res[i]
}
return ans
};