• leetcode-6-Z字形变换


    题目描述:

     将字符串 "PAYPALISHIRING" 以Z字形排列成给定的行数:
    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

     

    要完成的函数:

    string convert(string s, int numRows) 

     

    说明:

    1、这道题给定一个字符串s和行数,要求将字符串按z字形排列,具体见“题目描述”中举的例子。

    排列完之后,再按行读取,最后输出新的字符串结果。

     

    2、这道题感觉比easy题难一点点,但是比上次做的琐碎无比的medium好得不要太多!

    这道题我们只要明白规律就可以了,不用真的去把字符串排列成z字形存储起来,再按行读取的~

    举个例子,比如,s = "PAYPALISHIRING", numRows = 4

    P     I    N
    A   L S  I G
    Y A   H R
    P     I

    当行数为4时,我们可以看到每座“山”(从P到L)有6个元素,而我们一共有3座“山”。

    所以我们需要的是字符串中第0个元素,第6个元素,第12个元素。(不断加6)

    以及第二行的字符串中第1个元素,第5个元素,第7个元素,第11个元素,第13个元素。(加4加2,再重复)

    以及第三行的字符串中第2个元素,第4个元素,第8个元素,第10个元素。(加2加4,再重复)

    以及第四行的字符串中第3个元素,第9个元素。(不断加6)

     

    我们可以发现什么规律?

    我们可以根据numRows和字符串s的长度,知道有几座“山”,知道每座“山”的元素个数。

    进而可以根据每座山的元素个数,得到字符串中的坐标。

    比如上述例子中,每座山的元素个数是6,所以字符串中的坐标是0,6,12(不能超出字符串的长度)

    接着,我们从第二行的1开始,这时候要加4,再加6-4=2,不断地加,得到坐标是1,5,7,11,13(不能超出字符串的长度)

    再接着,从第三行的2开始,这时候要加2,再加6-2=4,不断地加……

    最后,从最后一行的3开始,这时候要加6-0=6,不断地加……

     

    如此这般,便可得到新的字符串,代码如下:(附详解)

        string convert(string s, int numRows) 
        {
            if(numRows==1)//边界情况,如果只有1行,那么直接返回原本的字符串
                return s;
            int s1=s.size(),s2=2*numRows-2,s3=s2,index=0,index1,count=0;//s2表示山峰的元素个数
            string res=s;
            for(int i=0;i<numRows;i++)//逐行处理
            {
                index1=index;//记录一下index的值,最开始为0,接着是1,再接着是2……
                while(index<s1)//每一行中只要坐标index不超过字符串的长度,那么不断处理
                {
                    if(s3==s2)//如果是第一行
                    {
                        res[count]=s[index];
                        index+=s3;
                        count++;
                    }
                    else if(s3==0)//如果是最后一行
                    {
                        res[count]=s[index];
                        index+=(s2-s3);
                        count++;
                    }
                    else//如果是中间行
                    {
                        res[count]=s[index];
                        index+=s3;
                        count++;
                        if(index<s1)//不能超过字符串的长度
                        {
                        	res[count]=s[index];
                        	index+=(s2-s3);
                            count++;
    		   }
                    }
                }
                s3-=2;//处理完一行之后,s3减去2
                index=index1+1;//更新index的值
            }
            return res;//最后返回新的字符串
        }
    

    上述代码实测16ms,beats 95.97% of cpp submissions。

  • 相关阅读:
    CentOS7安装MySQL5.7
    python基础 元组操作
    初识Python Python的历史(转)
    Python基础 基本数据类型
    createEvent 流沙
    GetLogicalDriveStringS获取驱动器根路径 流沙
    监控文件系统用得到的API 流沙
    Windows I/O 操作CreateFile 流沙
    脚本加入域 流沙
    WMI事件 流沙
  • 原文地址:https://www.cnblogs.com/chenjx85/p/9396640.html
Copyright © 2020-2023  润新知