[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 s, int numRows);

Example 1:
Input: s = "PAYPALISHIRING", numRows = 3
Output: "PAHNAPLSIIGYIR"

Example 2:
Input: s = "PAYPALISHIRING", numRows = 4
Output: "PINALSIGYAHRPI"
Explanation:
P I N
A L S I G
Y A H R
P I

Z字形变换。

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:

P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zigzag-conversion
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

题意是给一个正常的字符串,和一个参数 numRows,请以 Z 字形表示出来。例子,

Example:

Input: s = "PAYPALISHIRING", numRows = 4
Output: "PINALSIGYAHRPI"
Explanation:

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

如例子所示,input字符串被展示成了4行。这个题不涉及算法,是一道实现题,我这里介绍一个看到的非常好的YouTube视频。我会结合这个图讲思路,图也来自于视频。
Example

思路是用Java创建一个 StringBuilder array,里面加入 numRows 个 StringBuilder,然后遍历 input。首先是从上往下竖直的部分,因为已经知道了行数所以遍历的时候用 sb[i].append(c[index++]); 写入字符,i 是在 track 行数,index 是在 track 字符串。当 i == numRows 的时候,会跳出这个循环;

接下来是从左下到右上的部分,因为P已经在第一个 for 循环写进去了所以接下来要写A和L。如果所示,斜向上的元素始于 sb[numRows - 2](原因在于sb[numRows - 1]是最下面一行),止于sb[1](sb[0]是第一行),遍历依然是用 sb[i].append(c[index++]); 写入字符。写入所有字符之后,将 StringBuilder array 里面所有的 StringBuilder append 在一起,再 convert 成 string 输出。

复杂度

时间O(n)
空间O(n) - StringBuilder

代码

Java实现

class Solution {
    public String convert(String s, int numRows) {
        // corner case
        if (numRows == 1 || s.length() <= numRows) {
            return s;
        }

        // normal case
        StringBuilder[] sb = new StringBuilder[numRows];
        for (int i = 0; i < numRows; i++) {
            sb[i] = new StringBuilder();
        }

        int index = 0;
		// 一开始是往下走
        boolean down = true;
        for (char c : s.toCharArray()) {
            rows[index].append(c);
            index += down ? 1 : -1;
			// 如果遇到了第一行或者最后一行,就改变方向
            if (index == 0 || index == rows.length - 1) {
                down = !down;
            }
        }

        StringBuilder res = new StringBuilder();
        for (StringBuilder row : sb) {
            res.append(row);
        }
        return res.toString();
    }
}
posted @ 2020-03-14 03:32  CNoodle  阅读(457)  评论(0)    收藏  举报