題目描述
題目難度:中等
將一個給定字符串根據給定的行數,以從上往下、從左到右進行 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,和笨一點的方法性能差異還不算太大。
看了下最優解法其實思路都是一樣的,最優解法比我的解法的優勢在於,我竟然創建了二維數組,其實不用創建二維數組,字符串是可以直接拼接起來的。囧囧囧