力扣刷题百天计划 Day4 Z 字形变换

学习目标:

我会持续更新我独特的算法思路,希望能给大家带来不一样的思维拓展!
如果大家感觉有帮助的话,欢迎点赞关注支持哦!
你们的鼓励是我坚持下去的动力!
!!!

力扣题库第六题 官方链接


学习内容:

Z 字形变换

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:

P   A   H   N
A P L S I I G
Y   I   R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

示例 1:

输入:s = “PAYPALISHIRING”, numRows = 3
输出:“PAHNAPLSIIGYIR”
示例 2:
输入:s = “PAYPALISHIRING”, numRows = 4
输出:“PINALSIGYAHRPI”
解释:
P I N
A L S I G
Y A H R
P I
示例 3:

输入:s = “A”, numRows = 1
输出:“A”

提示:

1 <= s.length <= 1000
s 由英文字母(小写和大写)、',''.' 组成
1 <= numRows <= 1000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zigzag-conversion

学习时间:

2022.1.10


学习产出:

思路一
在这里插入图片描述
为什么执行用时会这么长?
因为算法逻辑不够巧妙,算是硬解出来的结果。但是设计思路还是蛮巧妙的!

解题思路
在这里插入图片描述
1.首先我们可以利用二维数组去存放这个Z字序列,然后按顺序读取这个二维数组就可以得到结果
2.我们如何去构建这个二维数组?首选,得到数组的行数和列数。行数肯定就是numRows,那么列数呢?仔细分析不难发现,列数其实就是字符串s的长度除以二加一。
3.我们如何将这个按Z字顺序放入呢?我们只需要按从上往下的顺序依次将字符串的字符一个个放入就行了。为此,我写了一个方法就是从字符串获得一个字符,其实这个过程可以用队列来完成,但是逻辑比较简单,我就用一个指针来代替了。
4.重点来了,我们是先遍历第一列,再遍历第二列。按照题目的要求,我们可以发现规律,如果行数是4,那么两个长列之间会隔两个短列,如果行数是3,那么两个长列之间会隔一个短列。其实很简单,就是短列部分的第一个和最后一个没有元素。那么我们怎么知道当前列是长列还是短列呢?按索引,我们可以将当前索引对numRows-1求余,如果为0,则是长列。比如索引0,长列,此时numRows为3,那么对其求余下一个为0的是2。2%(3-1)==0
5.我们已经知道如何判断长列和短列,我们就可以用两个for循环去遍历整个二维数组。如果是长列,则从上往下写入就行。如果是短列,则从下往上写入,出去最边上的两个点以外。我们在写长列的时候,可以对整个列写入,但是写短列的时候,写一个就得退出,然后去写下一个列。因为短列一列只有一个。
6.我们在字符串全部取完之后,就将#写入。因为Char数组如果不赋值,默认为’\u0000’,所以我们在输出结果的时候,只需要用两个for循环遍历这个二维数组,然后判断,如果不是#或者\u0000,则记录下来。
7.将记录下来的字符串返回,则是我们想要的Z字符串。

public class Solution {
    
    
    public string Convert(string s, int numRows) {
    
    
        //(s.Length/numRows)*2-1就是Z型数组长度
        //numRows就是宽度
        //s的长度除以宽度就是 最长的列的个数
        //Z型数组长度减去最长的列的个数 就是短列的个数
        //如果传入s长度14  rows为3
        //那么Z型数组长度为(14/3)*2-1=7
        //最长列个数为14/3 为4
        //短列为7-4 为3
        //其次我们还需要用长度
        
        if(s.Length==0||s.Length==1||numRows==1)return s;

        int ArrayLength=s.Length/2+1;   //Z型数组长度   7
        int LongLength=(s.Length/numRows);
        int ShortLength=ArrayLength-LongLength;
        int between=numRows-2;  //短的        //2
      
        char[,] rows=new char[numRows,ArrayLength];
        
        int curindex=-1; //现在放入的个数
        
        for(int i=0;i<ArrayLength;i++){
    
      //0-6
            for(int j=0;j<numRows;j++){
    
       //0-2
               // if(curCount>=s.Length){
    
    
               //     rows[j,i]='#';
               //     continue;
               // }

                if((i%(between+1)!=0&&i!=0) ){
    
     //是短列
                    if(numRows>2){
    
    
                        if(j==0||j==numRows-1){
    
     //奇数列头尾两个不设值
                            rows[numRows-i%(between+1)-1,i]='#';
                        }else{
    
    
                            rows[numRows-i%(between+1)-1,i]=GetOneChar();
                            break;
                        }
                    }else{
    
    
                        rows[numRows-i%(between+1)-1,i]=GetOneChar();
                        break;
                    }
                }else{
    
    
                    rows[j,i]=GetOneChar();
                } 
                
            }
        }

        string ss="";
        for(int i=0;i<numRows;i++){
    
    
            for(int j=0;j<ArrayLength;j++){
    
    
                if(rows[i,j]!='#'&&rows[i,j]!='\u0000'){
    
    
                    ss+=rows[i,j];
                }
            }
        }

        ss.Replace("\u0000", string.Empty);
        return ss;


        char GetOneChar(){
    
    
            curindex++;
            if(curindex>=s.Length){
    
    
                 return '#';
            }else{
    
    
                return s[curindex];
            }
        }
    }
}

作者:荷兰猪小灰灰
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

猜你喜欢

转载自blog.csdn.net/m0_48781656/article/details/122416452