Leetcode #6 ZigZag Conversion ZigZag翻转 解题小节

1 原题

ZigZag Conversion 原题

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

Leetcode #6 ZigZag Conversion ZigZag翻转 解题小节_第1张图片
以此类推,而题目的要求就是按行输出,那么上面两个的输出就分别是
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();

    }
}

最后 点这里关注我

你可能感兴趣的:(LeetCode,字符串,翻转,ZigZag)