「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战」。
题目描述
-
将一个给定字符串 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"
提示:
1 <= s.length <= 1000 s 由英文字母(小写和大写)、',' 和 '.' 组成 1 <= numRows <= 1000
思路介绍
我们先来推导下规则:
第0行: 0 - 6 - 12 - 18
==> 下标间距 6 - 6 - 6 ==> 下标间距 step - step - step
第1行: 1 - 5 - 7 - 11 - 13
==> 下标间距 4 - 2 - 4 - 2 ==> 下标间距step-21(行)-21(行)-step-21(行)-21(行)
第2行: 2 - 4 - 8 - 10 - 14 ==> 下标间距 2 - 4 - 2 - 4 ==> 下标间距step-22(行)-22(行)-step-22(行)-22(行)
第3行:3 - 9 - 15 - 21
==> 下标间距间距 6 - 6 - 6 ==>下标间距step - step - step
可以得出以下结论:
- 起始下标都是行号
- 第0层和第numRows-1层的下标间距总是step 。
- 中间层的下标间距总是step-2行数,2行数交替。
- 下标不能超过len(s)-1
整体的思路是遍历字符串,遍历过程中将每行都看成新的字符串构成字符串数组,最后再将该数组拼接起来即可 如果 numRows=1numRows=1 则说明当前字符串即为结果,直接返回 否则整个字符串需要经历,向下向右,向下向右,这样的反复循环过程,设定 downdown 变量表示是否向下,locloc 变量表示当前字符串数组的下标 如果 downdown 为 truetrue,则 loc+=1loc+=1,字符串数组下标向后移动,将当前字符加入当前字符串中 如果 downdown 为 falsefalse,则表示向右,则 loc-=1loc−=1,字符串数组下标向前移动,将当前字符加入当前字符串中 时间复杂度:O(n)O(n),nn为字符串s的长度
代码
class Solution {
public String convert(String s, int numRows) {
if(numRows == 1)
return s;
StringBuffer[] sbs = new StringBuffer[numRows];
for (int i = 0; i < numRows; i++) {
sbs[i] = new StringBuffer();
}
int flag = 1;
int n = 0;
for (int i = 0; i < s.length(); i++) {
sbs[n].append(s.charAt(i));
if(n == 0 || n == numRows - 1)
flag = flag == 0 ? 1 : 0;
if(flag == 0) {
n++;
}
else n --;
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < numRows; i++) {
sb.append(sbs[i].toString());
}
return sb.toString();
}
}
运行结果
执行结果:通过
执行用时: 6 ms
内存消耗: 39.1 MB
复杂度分析:
时间复杂度:O(n)
\