算法实战(六)Z 字形变换
一.前言
之前因为第五题最长回文字符串需要使用到dp解法,所以我花了很长的时间来研究dp(因为每天又要上班,加上这段时间事情比较多,所以花了三个星期才搞定),好不容易算入了个门,有兴趣的同学可以看看我写的dp的文章,话不多说,今天开始继续刷题。
二.题目
题目:将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "LEETCODEISHIRING"
行数为 3 时,排列如下:
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"
。
请你实现这个将字符串进行指定行数变换的函数:string convert(string s, int numRows);
示例1:输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
示例2:输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:
三.解题思路
解法1:二维数组
对于这种字符串变换的问题,我向来都是很头疼,一开始认为变化太多了很复杂,实际分析了一下这个题目后,发现并没有我想象的那么难。给定了一个行数后,对于字符串的走法,只有两种一种是沿着当前这一列往下走,一种是斜着往上走。我们只要判断一下,什么时候需要往下,什么时候需要斜着往上走就行了。定义一个二维数组,将字符串存在对应的位置,遍历完字符串之后,再将数组中的字符拼接起来,就能得到我们要的结果。
代码如下:
class Solution {
public String convert(String s, int numRows) {
//首先,我们对额外情况进行一下过滤
if (s == null || s.length() == 0 || numRows <= 1 || s.length() < numRows){
return s;
}
///创建一个stringBuilder,用来保存最后的结果
StringBuilder stringBuilder = new StringBuilder();
//创建一个二维数组,用来保存字符串到对应的位置
Character[][] arr = new Character[numRows][s.length()];
int num1 = 0;//行号
int num2 = 0;//列号
//遍历字符串
for (Character c : s.toCharArray()){
//当我们处于第一行时,或者上一行的字符不为null时,继续往下读
if (num1 == 0 || arr[num1 - 1][num2] != null){
arr[num1++][num2] = c;
//当到了最后一行时,往斜上方移动一个
if (num1 == numRows){
num1 = numRows - 2;
num2++;
}
}else {
//一直向斜上方移动
arr[num1--][num2++] = c;
}
}
//此时二维数组中记录了所有的字符了,按照顺序,取出不为空的字符
for (int i = 0; i < numRows; i++){
for (int j = 0; j < arr[0].length; j++){
if (arr[i][j] != null){
stringBuilder.append(arr[i][j]);
}
}
}
return stringBuilder.toString();
}
}
说明:这种解法的好处是思路简单,题目在构建Z字形变化时和我们平时使用的二维数组刚好吻合,所以能让人直观的理解,缺点就是时间复杂度太高了,我们进行Z字形变化所用的时间复杂度是O(n),但是我们把二维数组中的字符重新取出却要耗费O(n^2),得不偿失,所以我就在想有没有什么更好的数据结构能够利用一下,可惜没想出来。
解法二:创建一个StringBuilder的list
这个是leetcode提供的官方解法,思路真的是相当之巧妙,创建一个StringBuilder的List,用来保存每一行的字符串,其他的思路和上面的类似,就是两种走法,往下走和往上走。只不过最后我们获得结果的时候,只需要把list中的StringBuilder凭借到一起就可以了。
代码如下:
class Solution {
public String convert(String s, int numRows) {
//首先,我们对额外情况进行一下过滤
if (s == null || s.length() == 0 || numRows <= 1 || s.length() < numRows){
return s;
}
List<StringBuilder> list = new ArrayList<>();
for (int i = 0; i < numRows; i++){
list.add(new StringBuilder());
}
boolean bool = true;
int cos = 0;//行号
//只有两个地方需要进行变化,一个是在第一行,一个时在最后一行
for (Character c : s.toCharArray()){
if (cos == numRows){
cos -= 2;
bool = false;
}
if (cos == 0){
bool = true;
}
if (bool){
list.get(cos++).append(c);
}else {
list.get(cos--).append(c);
}
} StringBuilder result = new StringBuilder();
for (StringBuilder stringBuilder : list){
result.append(stringBuilder);
}
return result.toString();
}
}
这样的时间复杂度就变成了O(n)了。这就是今天Z字形变化的两种解法,大家有什么不懂的或者有更加高深的看法,欢迎一起探讨。
算法实战(六)Z 字形变换的更多相关文章
- leetcode刷题六<z字形变换>
将一个给定字符串根据给定的行数,以从上往下.从左到右进行 Z 字形排列. 比如输入字符串为 时,排列如下: L C I R E T O E S I I G E D H N 之后,你的输出需要从左往右逐 ...
- Z 字形变换 C++实现 java实现 leetcode系列(六)
Z 字形变换 java实现 C++实现 将一个给定字符串根据给定的行数,以从上往下.从左到右进行 Z 字形排列. 比如输入字符串为 "LEETCODEISHIRING" 行数为 ...
- C#版[击败100.00%的提交] - Leetcode 6. Z字形变换 - 题解
版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...
- Leetcode题库——6.Z字形变换
@author: ZZQ @software: PyCharm @file: convert.py @time: 2018/9/20 20:12 要求: Z字形变换 将字符串 "PAYPAL ...
- LeetCode Golang 6. Z 字形变换
6. Z 字形变换 将一个给定字符串根据给定的行数,以从上往下.从左到右进行 Z 字形排列. 比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下: L ...
- Leetcode(6)Z字形变换
Leetcode(6)Z字形变换 [题目表述]: 将一个给定字符串根据给定的行数,以从上往下.从左到右进行 Z 字形排列. 比如输入字符串为 "LEETCODEISHIRING" ...
- Java实现 LeetCode 6 Z字形变换
6. Z 字形变换 将一个给定字符串根据给定的行数,以从上往下.从左到右进行 Z 字形排列. 比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下: L ...
- 算法题--Z字形变换
题目描述 将一个给定字符串根据给定的行数,以从上往下.从左到右进行 Z 字形排列. 比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下: L C I ...
- 算法题-Z 字形变换
描述 将一个给定字符串根据给定的行数,以从上往下.从左到右进行 Z 字形排列. 比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下: L C I R ...
随机推荐
- Android之Context和Activity互相转换
1.context转换为activity Activity activity = (Activity) context; 2.从activity得到context 在activity的方法中用cont ...
- MariaDB——数据库集群
Mariadb数据库集群 mariadb主从 主从多用于网站架构,因为主从的同步机制是异步的,数据的同步有一定的延迟性,也就是说可能会导致数据丢失,但是性能比较好,因此网站大多数 用的是主从架构的数据 ...
- save the transient instance before flushing错误解决办法
错误原因: new了一个新对象,在未保存之前将它保存进了一个新new的对象(也即不是持久态). 解决办法: 在保存或更新之前把这个对象查出来(这样就是一个持久态) <set name=" ...
- 28 最小的K个数
题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 思路: 解法1:对于小规模数据,可以采用类似前题的快速排序思路 ...
- php循环语句for while do while的用法
循环结构 一.while循环 while(表达式){ 循环体;//反复执行,直到表达式为假} <?php$num = 1; while ($num <= 10){ print &qu ...
- Django 3.0 中连接mysql 8.0,可以不使用pymysql ,升级Mysqlclient即可
python 中,连接mysql一般都推荐用pymysql ,而且在django中,网上的教程都是这么连接mysql的. import pymysql pymysql.install_as_MySQL ...
- 「JSOI2007」建筑抢修
传送门 Luogu 解题思路 显然先把所有楼按照报废时间递增排序. 然后考虑 \(1\cdots i-1\) 都能修完, \(i\) 修不完的情况. 显然我们在这 \(i\) 个里面至多只能修 \(i ...
- Pycharm 报错 Environment location directory is not empty 解决
新电脑clone项目后发现Project Interpreter无法配置, New environment 选择后无法应用, 鼠标悬停在Location 提示 Environment location ...
- 图的数据结构的实现与遍历(DFS,BFS)
//图的存储结构:const int MAXSIZE = 10;//邻接矩阵template<class T>class MGraph {public: MGraph(T a[], ...
- Day10:关于桃子的和关于游戏新的设想(顺手做个记录孩子吃喝拉撒的工具)
公历2015年6月3日~ 北京时间晚上8:42~ 在美中宜和~ 一个叫桃子的小美女出生了! 没错!小桃子终于出生了!真心不容易啊! 6月3日 03:00 AM 老婆推我,叫我起来,她说她肚子疼,还想上 ...