【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)\)
posted @ 2022-09-05 20:10  帕图纳克斯  阅读(72)  评论(0编辑  收藏  举报