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

Z字形不太好表示,我们采用W型来表示,实际效果是一样的
字符会按照W型不断地排列下去,我们可以先归纳出其中的规律

0                            2n-2
 1                       2n-3    2n-1
  2                  2n-4            2n
   3             2n-5                  2n+1
    ...       ...                          ...            ...
       n-2   n                                3n-4    3n-2
          n-1                                     3n-3

以2n-2为循环,第k个循环内任一行左侧数+右侧数 = 2kn - 2k

以此撰写代码

写好后测试点"A" ,1没有通过,原来是我的首行判断中
while(j * 2 * numRows - 2 * j < len){这条判断条件
由于numRows=1,导致始终为真,跳转不出去。
添加了一段:如果numRows=1,直接返回原字符串,通过测试

完整代码:

#include
#include
#include
#include
#include
#include

using namespace std;

string convert(string s, int numRows){
    int len = s.size();
    int i,j;
    string res = "";
    if(numRows == 1){
        return s;
    }
    //首行 0, 2n-2 4n-4 ...
    j = 0;
    while(j * 2 * numRows - 2 * j < len){
        res += s[j * 2 * numRows - 2 * j];
        j++;
    }
    //中间行 2k(n-1)+i   2(k+1)(n-1)-i
    for(i = 1; i < numRows - 1; i++){
        j = 0;
        while(j * 2 * (numRows - 1) + i < len){
            res += s[j * 2 * (numRows - 1) + i];
            if((j + 1) * 2 * (numRows - 1) - i < len){
                res += s[(j + 1) * 2 * (numRows - 1) - i];
            }
            j++;
        }
    }
    //尾行 n-1,3n-3,...
    j = 0;
    while((j * 2 + 1) * (numRows - 1) < len){
        res += s[(j * 2 + 1) * (numRows - 1 )];
        j++;
    }
    return res;
}

int main(){
    string s = "A";
    int numRows = 1;
    cout << convert(s,numRows) << endl;
    return 0;
}

你可能感兴趣的:(6.Z字形变换)