LeetCode-中等-6-Z字形变换(C)
我觉得这更像N字形变化。
题目
打空格有点麻烦,WordPress用的html默认清除空格,题目中字符排列请到原题查看:https://leetcode-cn.com/problems/zigzag-conversion
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
示例 2:
输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:
L D R
E O E I I
E C I H N
T S G
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zigzag-conversion
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
这题得找规律,例子可以用1234567890,比较方便计算。
row表示行,oldPos表示待分配字符串中的位置,newPos表示新分配字符串中的位置,convertResult为新分配字符串,numRows为总行数。
易得:第一行与最后一行中,每列相差 2*(numRows-1)。
易知:第二行到倒数第二行中,每竖列相差 2*(numRows-1)。
容易看出:第二行到倒数第二行中,每竖列后的第 2*(numRows-1) - 2*(row-1) 位置有字符(这里也可以认为是前2*(row-1)个位置,但实际代码中不好操作)。
举例,对于1234567890字符串中,分成4行,如右表。
第二行的第二列,套公式row+2*(numRows-1),为2+2*3=8,右表该位置也为8。
而对于第三行第一列的后面一位,代入公式row+2*(numRows-1)-2*(row-1),为3+2*3-2*2=5,右表该位置也为5。
1 | 7 | ||
2 | 6 | 8 | |
3 | 5 | 9 | |
4 | 0 |
这样,我们先套一个大循环,遍历每行,再套一个循环,遍历各行中符合公式的值,就可以按顺序算出每个newPos对应的oldPos。
在后面的代码中,双层for循环中的第一个convertResult赋值为列赋值,后面的if内赋值为列后的斜线赋值。
代码
char * convert(char * s, int numRows){
char *convertResult;
int row, oldPos, newPos, charLength;
//初始化
charLength = strlen(s);
convertResult = (char*)malloc(sizeof(char)*(charLength+1));
convertResult[strlen(s)] = '\0';
newPos = 0;
//赋值
if(numRows==1) return s;
for(row=1; row<=numRows; row++){
for(oldPos=row; oldPos<=charLength; oldPos+=2*(numRows-1)){
convertResult[newPos++] = s[oldPos-1];
if(oldPos+2*(numRows-1)-2*(row-1)<=charLength && row!=1 && row!=numRows){
convertResult[newPos++] = s[oldPos+2*(numRows-1)-2*(row-1)-1];
}
}
}
return convertResult;
}
共有 0 条评论