【LeetCode】6. 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".

解法一:

维持一个数组StringBuilder[],将给定的String s 按照题目中所示的方法把每一个字符依次存进对应的行的StringBuilder中,在存的过程中有两种情况,一是竖直向下,一是斜向右上。最后将数组每一个index的字符串加在一起。时间复杂度 O(n).

代码如下:

public String convert(String s, int numRows) {
        char[] ss = s.toCharArray();
        int len = ss.length;
        StringBuilder[] sb = new StringBuilder[numRows];
        for (int i = 0; i < numRows; i++){
            sb[i] = new StringBuilder();
        }
        
        int index = 0;
        while (index < len){
            for (int i = 0; i < numRows && index < len; i++){
                sb[i].append(ss[index++]);
            }
            for (int i = numRows - 2; i >= 1 && index < len; i--){
                sb[i].append(ss[index++]);
            }
        }
        for (int i = 1; i < sb.length; i++){
            sb[0].append(sb[i]);
        }
        return sb[0].toString();
    }

解法二:
第一行和最后一行每一个元素current 和 next 相隔的距离一样,都是step = numRows * 2 - 2. 介于第一行和最后一行之间的,不仅要存vertical方向上的元素,还要存其对角线方向上的neighbor,并且这两个元素和各自对应的下一个周期一样(step = numRows * 2 - 2). 我们可以维持一个stringbuilder,先加第一行,再加第二行和倒数第二行,再加最后一行。时间复杂度 O(n)

代码如下:

 public String convert(String s, int numRows) {
        if (s == null || s.length() == 0 || numRows <= 1 || s.length() <= numRows){
            return s;
        }
        char[] ss = s.toCharArray();
        int len = ss.length, step = numRows * 2 - 2;
        StringBuilder sb = new StringBuilder();
        
        // first row
        for (int i = 0; i < len; i += step){
            sb.append(ss[i]);
        }
        
        // rows between 1st row and last row
        for (int rowIndex = 1; rowIndex < numRows - 1; rowIndex++){
            int verticalIndex = rowIndex;
            int nextIndex = step - verticalIndex;
            
            while (verticalIndex < len){
                sb.append(ss[verticalIndex]);
                verticalIndex += step;
                
                if (nextIndex < len){
                    sb.append(ss[nextIndex]);
                    nextIndex += step;
                }
            }   
        }
        
        // last row
        for (int i = numRows - 1; i < len; i += step){
            sb.append(ss[i]);
        }
        return sb.toString();
    }

此解法的运行时间少于解法一

两个解法的思路均来源于leetcode discussion.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值