菜鸡每日一题系列打卡6天
每天一道算法题目
小伙伴们一起留言打卡
坚持就是胜利,我们一起努力!
题目描述(引自LeetCode)
将一个给定字符串根据给定的行数,以从上往下、从左到右进行Z字形排列。比如输入字符串为"LEETCODEISHIRING"行数为3时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
示例 2:
输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:
L D R
E O E I I
E C I H N
T S G
题目分析
根据题目描述,比较容易想到的办法主要有两种。第一种是模拟字符串的Z字形排列,并利用多个StringBuilder对象分别记录每一行的结果,最后将每一行的结果进行拼接即可得到结果。但这种方法需要创建并维护多个StringBuilder变量,当numRows较大时,创建对象的开销是值得考虑的。因此,本文使用的是第二种解决方法,寻找字符串Z字形排列之后的字符与下标的规律,并仅创建一个StringBuilder即可完成字符串的拼接。
代码实现
class Solution {
public String convert(String s, int numRows) {
// 特殊情况处理
if (numRows < 1) {
throw new IllegalArgumentException("no solution!");
}
if (s == null || s.length() == 0 || numRows == 1) {
return s;
}
// 用于字符串拼接
StringBuilder builder = new StringBuilder();
// 行数转化为行号(默认从0开始)
int row = numRows - 1;
// 起始行(末尾行)元素之间的下标间隔
int step = 2 * row;
// 针对每一行遍历
for (int i = 0; i < numRows; i++) {
// 记录索引的变化
int index = i;
// 记录非起始行(末尾行)间隔的变化
int interval = step - 2 * i;
while (index < s.length()) {
builder.append(s.charAt(index));
index += (i == 0 || i == row) ? step : interval;
interval = step - interval;
}
}
// 转换为字符串输出
return builder.toString();
}
}
代码分析
对代码进行分析,遍历操作完成了对s中所有字符的一次访问,因此,时间复杂度为O(n);由于需要额外的空间存储变换之后的字符串,因此,空间复杂度为O(n)。
执行结果
关注公众号有理想的菜鸡,和菜鸡一起打卡吧!点个在看让更多小伙伴看到。
学习 | 工作 | 分享
????长按关注“有理想的菜鸡”
只有你想不到,没有你学不到