题目难度:中等
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。比如输入字符串为 “LEETCODEISHIRING” 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“LCIRETOESIIGEDHN”。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
示例 2:
输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:
L D R
E O E I I
E C I H N
T S G
本题读题的时候看起来有点绕,其实思索一下并不难。其实就是将字符按照如下图排列,再按行拼接即可。
效率最高的方法肯定是一层循环直接将每个字符应该变换到的位置计算出来直接生成结果,但是思考了一会把自己饶了进去囧。就先按照稍微笨一点的方法实现一下。
1.创建一个二维数组。
2.一层循环将当前字符push到应该进入的第几行。
3.将二维数组转为字符串
/**
* @param {string} s
* @param {number} numRows
* @return {string}
*/
var convert = function(s, numRows) {
let result = [];
let order = true;
let currentPush = 0;
let signAry = [];
let flag = false;
for(let i = 0; i < numRows; i ++) {
signAry.push([]);
}
for(let i = 0; i < s.length; i ++) {
signAry[currentPush].push(s[i]);
if(order) {
currentPush ++;
}else {
currentPush --;
}
if(currentPush >= numRows - 1 || currentPush <= 0) {
order =!order;
}
if(numRows === 1) {
currentPush = 0;
}
}
for(let i = 0; i < signAry.length; i ++) {
result += signAry[i].join('');
}
return result;
};
思考&实现总用时:约20分钟
想要用效率更高的方法占据了大部分时间
运行结果
执行结果:通过
执行用时 :108 ms, 在所有 javascript 提交中击败了60.92%的用户
内存消耗 :41.9 MB, 在所有 javascript 提交中击败了35.44%的用户
/**
* @param {string} s
* @param {number} numRows
* @return {string}
*/
var convert = function (s, numRows) {
if (numRows == 1) {
return s
}
let row = [];
for (let i = 0; i < numRows; i++) {
row[i] = ''
}
let down = false, line = 0;
for (let x of s) {
row[line] += x;
if (line == 0 || line == numRows - 1) {
down = !down
}
line += down ? 1 : -1
}
let str = '';
for (let x of row) {
str += x
}
return str
};
最优解法用时76ms,和笨一点的方法性能差异还不算太大。
看了下最优解法其实思路都是一样的,最优解法比我的解法的优势在于,我竟然创建了二维数组,其实不用创建二维数组,字符串是可以直接拼接起来的。囧囧囧