6.Z字形变换

6. 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"

 

思路:

定义一个最终字符串fin,定义numsRow个整数,分别代表各行头部指针,在fin中找出对应行位置,将指针指向对应位置,再讲s中的字符串按行顺序输入给fin即可

步骤:

     1.根据每行元素个数,计算指针位置;

     2.根据s[i]中元素所在位置,计算所在行,并使用指针赋值给fin,同时指针+1;

代码:

class Solution {
public:
    //思路,定义一个一维数组,获取numRows个指针,分别指向每行的开始所对应的位置
    //在对s遍历时,按顺序输入对应行就可以的到一个排序后的字符串。
    string convert(string s, int numRows) {
        //fin申请空间与s相等;  
        string fin;
        fin.assign(s);        
        //根据规律,可以看为一个周期函数T;
        //i%T为其在周期中的位置,i/T为其所在周期
        int T=(numRows-2)*2+2; //可以优化为(numRows-1)*2,计算机来说区别不大 
        //计算的到每行元素个数; 取4个指针指向开头,填满就行;
        vector<int> state; 
        int length=0;
        int Tnum=s.size()/T; //完整周期数
        int Cnum=s.size()%T;  //多余字符个数
        for(int i=0;i<numRows;i++){         
          
            int thelen=0; //此行长度;
            state.push_back(length);
            //计算该行长度是由于第0行和最后一行只有一个字符,所以单独计算;
            if(i==0) 
                {thelen+=((Cnum!=0)?Tnum+1:Tnum);}

            else if(i==numRows-1)
                thelen=Cnum<numRows?Tnum:Tnum+1;
            else{
                thelen+=Tnum*2;  //个数先加上满周期有的,未满周期另外计算;
                if(Cnum<=numRows&&Cnum>=i+1)
                     thelen+=1;
                else if(Cnum>numRows)
                     thelen+=(T-i+1<=Cnum)?2:1; //T-i+1为如果未满周期右方第i行刚好为最后一个字符时的Cnum值
            }
            length+=thelen;
        }
       for(int i=0;i<s.size();i++)
        {
            // 先判断为第几行,再存入数据;
            unsigned int row=0;
            row=(i+1)%T; //先判断是一个周期的第几个数
            if(row>numRows)
            row=T-row+1;      //原式row=T+1(将周期补全至下一个周期第一个数)  -  row(还有多少数)+1-1;
            else
            row-=1;
            fin[state[row]++]=s[i];
        }
        return fin;
    }
};

 

 

上一篇:idea Failed to clean project Failed to delete target


下一篇:qt 文本流&数据流