[Leetcode] ZigZag Conversion 波浪形打印字符串

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:app

string convert(string text, int nRows);
convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR".模塊化

畫圖找規律法

複雜度

O(N) 時間 O(N) 空間函數

思路

打印題,二話不說,畫圖,標數字,找規律。
這題實際上是EPI這本書裏7.11題(Write a string sinusoidally),書裏的題規定k=3,在leetcode裏k做爲參數,因此更難了。
leetcode的這個例子的圖很是反人類,其實能夠把它畫得優美一些,像正弦函數的波浪形:ui

P       A       H       N
  A   P   L   S   I   I   G
    Y       I       R

舉個別的例子本身畫一下:
圖片描述
經觀察發現,對於每一個nRows(爲了簡便用k表示),都有一個本身的magic number = 2 * k - 2,magic number的用處請往下看:
下面咱們研究一下怎麼打印這個波浪,大家感覺一下:this

  1. 經觀察,一共要打k行,每行打的規則是相同的,因而打每行的函數單獨提出來:fill();spa

  2. 研究一下fill這個函數怎麼寫,經觀察,發現打印一行須要三個參數,startIndex, distance1, distance2,且distance1 + distance2 = magic number;可是,第一行和最後一行是兩個特例,他們的distance1 = distance2 = magic number,單獨考慮一下就好了;code

  3. 來細化一下fill()這個接口:blog

    void fill(StringBuilder sb,    //存結果,必須有
              int start,           //這行從哪開始打?第幾行就從幾打,即k
              int initialDistance, //下個字符去哪找?加上distance就是下個字符
              int magic,           //magic number
              String s)            //原字符串,必須有
  4. 注意上面這個initialDistance參數,每行兩個字符的distance不是固定的,他的規則是(magic=8,initialDistance=2):2,6,2,6,2,6....想獲得下一個distance用magic減去當前distance就好啦;接口

  5. 下面研究一下對於每一行最開始應該傳進去的initialDistance是多少。經觀察,打第0行的時候,initialDistance是magic number,第1行的initialDistance是magic number - 2, 第2行的是magic number - 4...總之打完一行把initialDistance減去2就好了;
    6.注意了,第0行和最後一行的distance是固定的,都是magic number,要寫一句if;

注意

模塊化編程:把fill函數提取出來,這樣邏輯更爲清晰
本方法得到:Your runtime beats 95.36% of Java submissions.

代碼

fill方法:

public void fill(StringBuilder sb, int start, int initialDistance, int magic, String s) {
        while (start < s.length()) {
            if (initialDistance == 0)    //對應思路講解第6條
                initialDistance = magic;
            sb.append(s.charAt(start));
            start = start + initialDistance;  
            initialDistance = magic - initialDistance;//對應思路講解第4條
            
        }
    }

主程序:

public class Solution {
    public String convert(String s, int numRows) {
        if (numRows == 1)
            return s;
        StringBuilder sb = new StringBuilder();
        int magic = numRows * 2 - 2;
        int initialDistance = magic;
        for (int i = 0; i < numRows; i++) {
            fill(sb, i, initialDistance, magic, s);
            initialDistance = initialDistance - 2; //對應思路講解第5條
        }
        return sb.toString();
    }
}
相關文章
相關標籤/搜索