- 题目描述:
将一个给定字符串 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”
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zigzag-conversion
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
- 解题思路:
这题的题目本来是Z字型变换,但是我觉得这题应该是N字型变化更加贴切一点,所以更改了题目。
这题的主要思路就是寻找到所有数所在行数与字符串索引之间的关系,我们可以发现循环的周期是2*numRows - 2 ,然后再来解决中间的数对应的行数,可以这样来理解,就是用索引对(2numRows - 2)进行取余的运算得到余数K,这样K就是代表此数在一个小周期中所在第几个,若K<numRows-1,则K就是所在的行数,若K>=numRows-1,则**(2numRows - 2 )- K就是所在的行数,下面证明这个式子式怎么得出的。**
首先K代表的是在小周期中第几个,当K>numRows-1的时候K-numRows代表的就是中间的数从下往上数第几个,所在的行从下往上数就是第K-numRows+1行,从上往下数就是第numRows-(K-numRows+1)+1 行,化简即可得到2*numRows - 2-K - 解题代码
/** i%(2n-2) = row;
z字型变换的周期是2numRow-2
*/
string s2; // 用来保存新的字符串
int index;
if(numRows == 1){
return s;
}else{
for(int i = 0;i < numRows;i++){
//用j来进行周期的取值
for(int j = 0; j + i < s.size() ; j += (2*numRows-2)){
s2 += s[j+i];
//来判断非第一行和非最后一行的时候来取两竖列中间的值
//数列中间的值的规律是
if(i != 0 && i != numRows-1 && j+(2*numRows-2)-i<s.size()){
s2 += s[j+(2*numRows-2)-i];
}
}
}
return s2;
}
- tips:
对于很多的这种数组变换行的算法题来说,首先应该做的就是找到元素索引和所在位置之间的对应规律,找到了规律及得到了题解。