将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:
P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/zigzag-conversion
思路:
- z自行变换其实是一个v型的循环, 即
p A H N
a p L S I I G
y I R
题目示例:可以分为以上循环,
因此我们找到循环次数, 以及每次循环的长度
-
v字形可以分成
p
a p
y 和 循环两部分。 -
通过以上循环得到目标数组, 遍历数组得到目标字符串。
-
时间复杂度, 其实是o(n); n 有可能比s.length大一些。
/**
* @param {string} s
* @param {number} numRows
* @return {string}
*/
var convert = function(s, numRows) {
if (numRows === 1) {
return s;
}
var length = s.length;
var roundLength = numRows*2 - 2;
var round = Math.ceil(length/roundLength);
var resultArr = [];
for (var i=0; i< numRows; i++) {
resultArr[i] = [];
}
var startIndex = 0;
var col = 0;
for (var i =0; i<round; i++) {
startIndex= vLoop(s, startIndex, col, numRows, resultArr);
col += numRows -1;
}
var resultStr = '';
for (var i=0; i< numRows; i++) {
var length1 = resultArr[i].length;
for (var j=0; j<length1; j++) {
if (resultArr[i][j] && resultArr[i][j] != '') {
resultStr += resultArr[i][j];
}
}
}
return resultStr;
};
/**
*
* @param {*} s : 要处理的字符串
* @param {*} startIndex : v循环开始的处理的子字符串index
* @param {*} startCol : v循环开始的数组col
* @param {*} numRows : 列数
* @param {*} resultArr : 存储的结果
*/
function vLoop(s,startIndex, startCol,numRows, resultArr) {
for(var i=0; i< numRows; i++) {
resultArr[i][startCol] = s.charAt(startIndex);
startIndex++;
}
for(var i=numRows -2; i>0; i--) {
resultArr[i][++startCol] = s.charAt(startIndex);
startIndex++;
}
return startIndex;
}