1 原题
The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)
P A H N
A P L S I I G
Y I R
And then read line by line: "PAHNAPLSIIGYIR"
Write the code that will take a string and make this conversion given a number of rows:
string convert(string text, int nRows);
convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR".
2 题目理解
这道题的标注是easy,理论上是很简单,但实际上还是需要动一下脑子的。
ZigZag什么意思,其实就是走一个锯齿形(Z)型的路线,不过从这里看着来更像是N字型的。假若题目给定了numRows,那么就是讲原有的数组的排列改成先往下走numRows,随后斜线numRows-2个,然后就正好重复一个周期了
假若我们有 1234567890 ,numRows=4
以此类推,而题目的要求就是按行输出,那么上面两个的输出就分别是
0615724839
0481357926
然后关键的就来了,如何转化的?
最傻的方法当然是开辟个二维数组,先放好,再输出,不过这里就不说那么弱智的方案了。。
仔细观察,我们可以看到ZigZag的非斜线重复周期是2*numRows-2,又因为我们知道第一列的取值的位置是什么,所以我们再得知每行的第一个后,自然可以很快的找出下一个非斜线上的元素。
不过除了首行和末尾行,其他行中间都有斜线夹杂着,不过这里也同样有规律,假设i=0时代表的是首行第一个,当前在中间的第i行,2*(numRows-i-1)就是其斜线上的位置,那么对于中间的行,其输出方式如下:
设
step=2*numRows-2
substep=2*(numRows-i-1)
输出
第i个字符,i+substep,i+step,(i+step)+substep,(i+step)+step,(i+2step)+substep….
很清楚了吧,同样是以step为周期,但是中间要多输出一个斜线的元素
可以自己画个图看看,不方便画图,或者网上搜图解是哪个搜也一大推
3 AC解
我给了一个分开首尾行处理的和整合在一起的,大家自取就好
public class Solution {
/**
* 多了if减少判断的,但是理论上
速度变慢。。只是leetcode的代码木有体现出来。。。
* */
public String convert2(String s, int numRows) {
if(numRows<2)
return s;
int n=s.length();
StringBuilder sb=new StringBuilder(n);
char[] chars=s.toCharArray();
//先处理第一行,第一行的重复周期是2*numRows-2
int step=2*numRows-2;
//处理中间的numRows-2行,每行应该有两个
for(int i=0;i<numRows-0;i++){
int substep=2*(numRows-i-1);
for(int j=i;j<n;j+=step){
sb.append(chars[j]);
if(i!=0 && i!=numRows-1 && j+substep<n)
sb.append(chars[j+substep]);
}
}
return sb.toString();
}
public String convert(String s, int numRows) {
if(numRows<2)
return s;
int n=s.length();
StringBuilder sb=new StringBuilder(n);
char[] chars=s.toCharArray();
//先处理第一行,第一行的重复周期是2*numRows-2
int step=2*numRows-2;
int i,j,substep;
for( i=0;i<n;i+=step){
sb.append(chars[i]);
}
//处理中间的numRows-2行,每行应该有两个
for(i=1;i<numRows-1;i++){
substep=2*(numRows-i-1);
for(j=i;j<n;j+=step){
sb.append(chars[j]);
if(j+substep<n)
sb.append(chars[j+substep]);
}
}
//最后一行
for( i=numRows-1;i<n;i+=step){
sb.append(chars[i]);
}
return sb.toString();
}
}
最后 点这里关注我