题目以及题解来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zigzag-conversion
将一个给定字符串 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);
示例 1:
输入:s = "PAYPALISHIRING", numRows = 3
输出:"PAHNAPLSIIGYIR"
示例 2:
输入:s = "PAYPALISHIRING", numRows = 4
输出:"PINALSIGYAHRPI"
解释:
P I N
A L S I G
Y A H R
P I
示例 3:
输入:s = "A", numRows = 1
输出:"A"
提示:
1 <= s.length <= 1000
s 由英文字母(小写和大写)、',' 和 '.' 组成
1 <= numRows <= 1000
class Solution {
public String convert(String s, int numRows) {
if (numRows == 1) return s;
List<StringBuilder> rows = new ArrayList<>();
for (int i = 0; i < Math.min(numRows, s.length()); i++)
rows.add(new StringBuilder());
int curRow = 0;
boolean goingDown = false;
for (char c : s.toCharArray()) {
rows.get(curRow).append(c);
if (curRow == 0 || curRow == numRows - 1) goingDown = !goingDown;
curRow += goingDown ? 1 : -1;
}
StringBuilder ret = new StringBuilder();
for (StringBuilder row : rows) ret.append(row);
return ret.toString();
}
}
个人思路
首先看到这个题的时候,我个人真的是大脑一片空白,于是直接去看参考答案分析了下,我觉得我们可能都被题目中的一些信息给干扰了,首先最大的干扰就是Z型图形的空格,其实最后的输出是没有空格的,每一行都输出出来即可。
然后还让我们无从下手的因素就是字符的编排方式,貌似是无规律的,其实我们应该试着手动的一个个字母去写,然后你就会发现,例如字符串是A,B,C,D,E,F,G 那么:
-
首先要知道这个字符串最多能存储几行,比如A,B,要求3行,但是实际上最多只能2行
-
知道最多存储的行数之后,比如字符串是A,B,C,D,E,F,G,要求存储3行,实际情况这个字符串也能存储3行,就可以开始了:
- 第一行存储A
- 第二行存储B
- 第三行存储C,这个是最后一行,接下来就需要往上到第二行存储了
- 第二行存储D
- 第一行存储E,这个是第一行,接下来就需要往下到第二行存储了
这样周而复始,是不是这么一看就是有规律了,就是上下是有个边界的,然后到头就需要回头打印字符。 程序也就是这么个逻辑,而是否掉头用变量 goingDown 来计算。
程序中:
if (curRow == 0 || curRow == numRows - 1) goingDown = !goingDown;
当第一行或者最后一行,回头!
程序中:
curRow += goingDown ? 1 : -1;
这个就是根据往哪儿回头来加减行,进行输出字符。
网友评论