[LeetCode] ZigZag Conversion

来源:互联网 发布:淘宝买万艾可需要处方 编辑:程序博客网 时间:2024/06/06 11:05

问题:
字符串 “PAYPALISHIRING”按照“之“字型排列如下:
这里写图片描述
横着读,字符串转换为”PAHNAPLSIIGYIR”
求这个字符转换的算法:string convert(string text, int nRows)

思路:
首先,这肯定是个数学问题。这种有规律的排列一定可以总结出数学公式来。
试试排个n=4的。
这里写图片描述

看第一行和最后一行,很容易看出来数学公式是啥。
第一行是1+6n,最后一行是4+6n.
这个6又是啥呢。可以再排个n=5位看看,或者直接推算。
总之,结论是6=242,也就是说每2n-2是个循环。

那么,每个字符该放在哪呢。再看一下上面的图形,根据刚才的结论,可以得到结果,对于第i位的字符,应该放在p=imod(2n2),if(p<n):p1;else:2np1.
从数学上看,这个公式相当的不优雅。但从计算机角度,这样刚好容易实现。

再考虑一下边界条件。
边界条件有两个,一个是只有一竖排,一个是只有一横排。

到此就可以写代码了。

public class Solution {    public String convert(String s, int numRows) {        int length = s.length();        //边界条件        if(length <= numRows || numRows < 2){            return s;        }        //用数组存一下每一行的数据。StringBuffer.append效率比String+高多了。StringBuilder更好,因为比起StringBuffer没有做线程同步。        ArrayList<StringBuilder> list = new ArrayList<StringBuilder>();        for(int l=0; l< numRows; l++){            list.add(new StringBuilder());        }        //除余做个循环,i先映射到index上,然后append到某个stringbuffer上。        for(int i=0; i<length; i++){            int index = (i+1)%(2*numRows-2);            //因为index本身是从小到大按序输入的,所以把小于的判断排到前面。            if(index == 0){                list.get(1).append(s.charAt(i));            }else if(index <= numRows){                list.get(index-1).append(s.charAt(i));            }else{                list.get(2*numRows - index -1).append(s.charAt(i));            }        }        StringBuilder result = new StringBuilder();        for(int l=0;l<numRows;l++){            result.append(list.get(l));        }        return result.toString();    }}
0 0
原创粉丝点击