题目
LeetCode: ZigZag Conversion
将字符串 "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
思路
这是一个找规律题,每次字母差是有规律的
第一行字母之间差为2n - 2
第二行子母之间差为2n - 4
和2
交替
……
倒数第三行字母间差为4
和2n - 6
交替
倒数第二行字母间差为2
和2n - 4
交替
倒数第一行字母间差为2n - 2
总结一下规律,除了第一行和最后一行,每次交替的值的和为2n - 2
,第一行和最后一行为2n - 2
,每一行第一次相差的值比前一行少2
代码
char* convert(char* s, int numRows) {
assert(s);
int size = strlen(s) + 1;
char* ret = (char*)malloc(size);
if (numRows == 1)
{
//单独处理特殊字符串
strncpy(ret, s, size);
return ret;
}
assert(ret);
char* cur = ret;
char* get = s;
int row_count = numRows * 2 - 2;//增量一直在变,总结一下规律
//假设numRows传入为n,可以画图找规律
//第一行增量为2n-2
//第二行增量为2n-4,2依次交替
//第三行增量为2n-6,4依次交替
//……每行增量减少2,直至增量变为2
//第n-1行增量为2,2n-4依次交替
//第n行增量比较特殊,为2n-2
int increment = numRows * 2;//每次的增量
int increment_tmp = 0;//作为增量的临时存储变量
for (int i = 0; i < numRows; i++)
{
//get作为获取当前字符的指针
get = s + i;
if (increment > 2)
{
//每次的增量减少2
increment -= 2;
}
else if (increment == 2)
{
//当前一次增量为2,将增量置为2n-2
increment = row_count;
}
increment_tmp = increment;
while (get - s < size - 1)
{
*cur++ = *get;
get += increment_tmp;
//变换增量
increment_tmp = row_count - increment_tmp;
if (increment_tmp == 0)
{
increment_tmp = row_count;
}
}
}
*cur = '\0';
return ret;
}