【JS】6. Z 字形变换
6. Z 字形变换
二维数组模拟
就是找出放单词位置的规律出来
var convert = function(s, numRows) {
//如果要求的行数都超过了字符串的长度或者本身行数要求就为1
const n=s.length,r=numRows;
if(r === 1 || r>=n){
return s;
}
//设每隔一定的周期字符串都会排成对应的 ‘V’ 字符
//可以发现当向下排R个时,到新的第一行的中间有R-2个字母
//因此可以让行变为 r+ r -2= 2*r-2
const ar=r*2-2;
//可以让每个周期 T 的列变为 1 + r-2
//那么行是固定的,列一共为 (r-1) * T
//根据观察T 为 [s.length-1]/(2*r-2) + 1
//因为认为最后一个周期为完整周期 像个'l'也不是没可能
const c=Math.floor((n+ ar -1)/ar)*(r-1);
//构建一个仅为值引用的二维数组
const mat=new Array(r).fill(0).map(()=>new Array(c).fill(0));
let x=0,y=0;
//先遍历字符串
for(let i=0;i<n;i++){
mat[x][y]=s[i];
// 如果满足 i mod ar < r-1的条件,则就要向下画
if(i% ar <r-1){
++x;
//而不满足的话,就是要向右上开始画了。
}else{
--x;
++y;
}
}
//之后就要按照题目规则重新弄成新的字符串
const res=[];
//获取每行的单词组
for(const row of mat){
//再根据每列获取单个单词
for (const ch of row){
if(ch !==0){
res.push(ch);
}
}
}
return res.join('');
};
复杂度分析
时间复杂度:\(O(r\cdot n)\),其中 \(r=\textit{numRows}\),\(n\) 为字符串 \(s\) 的长度。
空间复杂度:\(O(r\cdot n)\)。
按行访问
var convert = function(s, numRows) {
//首先根据“N”字符可以观察到,起码要numRows为3以上才可以形成该字符
//而摆在中间的,则为numRows-2,如果我们选择是按行访问,即数完第一行,再数第二行
//接着数第三行的话,那么其实可以发现为什么要考虑这些空格呢?其实可以用字符串合起来的啊!
//其次也没必要弄个二维矩阵出来,因为都是弄字符串了,一个竖直下来的一维数组就够用了。
//首先要弄出这个“N”字符先。
if(numRows===1) return s;
//一个存储行数组
let row=[];
//每个周期的除首位的
let cur=numRows-2;
//一个表示是否要拐角的flag变量
let dir=true;
let n=s.length;
//现在先遍历
for(let i=0;i<n;i++){
//如果要画第一个竖线
if(i<numRows){
row[i]=s[i];
}
//如果要画右斜向上线
else{
//看是否是拐角
if(cur===numRows-1 || cur===0){
dir=!dir;
}
//接着就要添加N字符对应的右上斜线了
row[cur]+=s[i]//空格不管它
//拐角的好处就用来帮助我们每个周期贴上对应行的字母
if(dir){
cur--;
}else{
cur++;
}
}
}
//最后“N”字符对应行的字母该有的都有了,那么要想这么打印出来。
//用reduce就可以实现每一行合并起来再打印,就必要用循环处理了。
return row.reduce((pre,cur)=>pre+cur,'');
};
复杂度分析
- 时间复杂度:\(O(n)\)
- 空间复杂度:\(O(numRows)\)