乘风破浪:LeetCode真题_006_ZigZag Conversion
乘风破浪:LeetCode真题_006_ZigZag Conversion
一、前言
到这里我们对基本的问题有了一定的理解,其中字符串的操作一直是一个比较困难的问题,这一点我们需要认真对待,采用合理的方案去解决问题。下面我们就看看将字符串按照某种格式排列之后再按行输出的问题。
二、ZigZag Conversion
2.1 问题理解


2.2 分析以解决问题
看到这样的问题我们最直接的想法就是构造一个二维数组,初始化成某种字符,然后按照题目给定的规则进行填充,填充完成之后按行进行遍历,将结果拼凑起来输出出去。这种方法复杂度为O(n~2)。因此我们进行优化,采用StringBuilder这样的结构来直接进行存储,能够将时间复杂度缩小到O(n)。
下面是官方的解法:
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();
}
}

我们的算法:
public class Solution {
/**
* 题目大意
* 输入一个字符串和指定的行数,将字符以Z字型输出。
*
* 解题思路
* 计算出字符的最大列数,根据列数和行数创建一个一维数组,再计算每个字符中一维数组中的位置,
* 再对一维数组中的字符进行紧凑操作,返回结果。
* </pre>
*
* @param s
* @param nRows
* @return
*/
public String convert(String s, int nRows) {
if (s == null || s.length() <= nRows || nRows == 1) {
return s;
}
int index = s.length();
int rowLength = 0; // 计算行的长度,包括最后换行字符
int slash = nRows - 2; // 一个斜线除去首尾所占用的行数
while (index > 0) {
// 竖形的一列
index -= nRows;
rowLength++;
// 斜着的列数
for (int i = 0; i < slash && index > 0; i++) {
rowLength++;
index--;
}
}
char[] result = new char[nRows * rowLength]; // 保存结果的数组,最后一列用于保存换行符
for (int i = 0; i < result.length; i++) { // 初始化为空格
result[i] = ' ';
}
int curColumn = 0; // 当前处理的行数
index = 0;
while (index < s.length()) {
// 处理竖线
for (int i = 0; i < nRows && index < s.length(); i++) {
result[rowLength * i + curColumn] = s.charAt(index);
index++;
}
curColumn++;
// 处理斜线
for (int i = nRows - 2; i > 0 && index < s.length(); i--) {
result[rowLength * i + curColumn] = s.charAt(index);
curColumn++;
index++;
}
}
// 对字符数组进行紧凑操作
index = 0;
while (index < s.length() && result[index] != ' ') { // 找第一个是空格的字符位置
index++;
}
int next = index + 1;
while (index < s.length()) {
while (next < result.length && result[next] == ' ') { // 找不是空格的元素
next++;
}
result[index] = result[next];
index++;
next++;
}
return new String(result, 0, index);
}
}
这样的算法其实就是笨办法了,首先计算出虚拟的二维数组需要的空间大小,然后实际上(物理上)用一维数组来表示,并且初始化为空,之后将源字符串的字符按照规则填到虚拟的二维数组中,其实是一维数组,最后将一维数组中的空格去除掉就得到了想要的结果,显然是一个O(n~2)的算法,没有官方的好。

三、总结
通过这样的一个例子,我们可以发现往往我们的原始想法都是暴力法,按部就班的来,只要稍微的优化一下就能变成更好的方法,得到更优质的结果,写更少的代码。
乘风破浪:LeetCode真题_006_ZigZag Conversion的更多相关文章
- 乘风破浪:LeetCode真题_041_First Missing Positive
乘风破浪:LeetCode真题_041_First Missing Positive 一.前言 这次的题目之所以说是难,其实还是在于对于某些空间和时间的限制. 二.First Missing Posi ...
- 乘风破浪:LeetCode真题_040_Combination Sum II
乘风破浪:LeetCode真题_040_Combination Sum II 一.前言 这次和上次的区别是元素不能重复使用了,这也简单,每一次去掉使用过的元素即可. 二.Combination Sum ...
- 乘风破浪:LeetCode真题_039_Combination Sum
乘风破浪:LeetCode真题_039_Combination Sum 一.前言 这一道题又是集合上面的问题,可以重复使用数字,来求得几个数之和等于目标. 二.Combination Sum ...
- 乘风破浪:LeetCode真题_038_Count and Say
乘风破浪:LeetCode真题_038_Count and Say 一.前言 这一道题目,很类似于小学的问题,但是如果硬是要将输入和结果产生数值上的联系就会产生混乱了,因此我们要打破思维定势. ...
- 乘风破浪:LeetCode真题_037_Sudoku Solver
乘风破浪:LeetCode真题_037_Sudoku Solver 一.前言 这次我们对于上次的模型做一个扩展并求解. 二.Sudoku Solver 2.1 问题 2.2 分析与解决 这道题 ...
- 乘风破浪:LeetCode真题_036_Valid Sudoku
乘风破浪:LeetCode真题_036_Valid Sudoku 一.前言 有的时候对于一些基础知识的掌握,对我们是至关重要的,比如ASCII重要字符的表示,比如一些基本类型的长度. 二.Valid ...
- 乘风破浪:LeetCode真题_035_Search Insert Position
乘风破浪:LeetCode真题_035_Search Insert Position 一.前言 这次的问题比较简单,也没有限制时间复杂度,但是要注意一些细节上的问题. 二.Search Insert ...
- 乘风破浪:LeetCode真题_034_Find First and Last Position of Element in Sorted Array
乘风破浪:LeetCode真题_034_Find First and Last Position of Element in Sorted Array 一.前言 这次我们还是要改造二分搜索,但是想法却 ...
- 乘风破浪:LeetCode真题_033_Search in Rotated Sorted Array
乘风破浪:LeetCode真题_033_Search in Rotated Sorted Array 一.前言 将传统的问题进行一些稍微的变形,这个时候我们可能无所适从了,因此还是实践出真知, ...
随机推荐
- PHP之string之ord()函数使用
ord (PHP 4, PHP 5, PHP 7) ord - Return ASCII value of character ord - 返回字符的 ASCII 码值 Description int ...
- 性能调优-CPU方面,内存方面
CPU调优 首先要清楚数据库应用的分类,一般分为两类:OLTP(Online Transaction Processing,在线事务处理)和OLAP(Online Analytical Process ...
- 腾讯云技术专家卢萌凯手把手教你Demo一个人脸识别程序!
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文来自腾讯云技术沙龙,本次沙龙主题为Serverless架构开发与SCF部署实践 卢萌凯:毕业于东南大学,曾就职于华为,熟悉云行业解决方案 ...
- 设计模式应用场景之Model设计中可以用到的设计模式
在开发中,不同的场景适用不同的设计模式.对于开发建模方面,可以根据模型的抽象类型设计成简单属性模式和复杂组合模式. 因为组合模式中的属性为多种类型对象,可操作性也比较灵活. 而针对这种复杂数据结构,有 ...
- [Mysql 查询语句]——集合函数
count() 统计记录条数 select count(*) from student; +----------+ | count(*) | +----------+ | +----------+ s ...
- Python(1):入门
安装: 在linux中一般都自带有python2.7的版本,如果想升级python到最新的版本可以参考其他博客(http://www.cnblogs.com/lanxuezaipiao/archive ...
- Android运行时权限开启问题
参考: http://www.cnblogs.com/whoislcj/p/6072718.html(重点这篇) https://www.jianshu.com/p/b4a8b3d4f587 http ...
- 选择适用才最好 盘点MySQL备份方式
我们要备份什么? 一般情况下, 我们需要备份的数据分为以下几种 数据 二进制日志, InnoDB事务日志 代码(存储过程.存储函数.触发器.事件调度器) 服务器配置文件 备份工具 这里我们列举出常用的 ...
- Vs2015+opencv2.4.10出现msvcp120d.dll丢失 opencv2410.props
今天vs2015配置好opencv编译运行会报错msvcp120d.dll丢失,只要把这个文件复制到你在第一步设置的Path环境变量路径里,和opencv的dll放在一起就行了.(初次配置完环境变量后 ...
- Hadoop源码学习笔记(1) ——第二季开始——找到Main函数及读一读Configure类
Hadoop源码学习笔记(1) ——找到Main函数及读一读Configure类 前面在第一季中,我们简单地研究了下Hadoop是什么,怎么用.在这开源的大牛作品的诱惑下,接下来我们要研究一下它是如何 ...