将字符串 "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<vector>
#include<ctype.h>
#include<stdio.h>
#include<cstdio>
#include<string>
#include<iostream>
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;
}
网友评论