[LeetCode]#6 ZigZag Conversion
2015-07-21 16:59
274 查看
一、题目
二、解析
完整的Z字型是有规律可循的,比如5层中,后面所有的数字都在重复0-8的过程,所以我们来看看哪里可以被我们所用:
1.3层中,第一行为04,5层中,第一行为08,这里我们发现,差值delta=2*(层数-1)。例如在5层中,第0行相同位置0和8相差8,第1行相同位置19相差8。好了,这里我们得打了第一个有用规则。继续往下看。
2.3层中,最后一行为2610,5层中,最后一行为41220,相差为8上面已经得到。统筹的看第一行与最后一行,我们发现这两行的元素是比较整齐的,中间没有插入的元素。所有这两行在做处理的时候,应该归为一类。
3.下面我们看最左边一行,都是0123..代表的是第几层,ok这个很容易
4.剩下最后的也是最复杂的,中间部分。拿5层中第1行为例:1791517,这里面其实有两部分内容。第一部分同第一行和最后一行一样,是比较整洁的元素,如1917,他们之间相差都是8.第二部分就是多出来的7和15,如何求的他们呢?这时我们看第一行1和7相差6,第二行2和6相差4,第三行3和5相差2,这里我们就找到了规律,即:7=1+6=1+2*3,6=2+4=2+2*2,5=3+2=3+2*1。这里,等号左边是我们要通过公式得到的,等号右边第一项是行数,第二项2*n,n就是总行数-当前行数。7(要求的)=1(目前是第一行)+2*3(总行数为4,从0开始-1当前行)。
OK到这里,我们已经找到了所有的规律,总结如下:
1.相同位置差距delta为2*(层数-1)
2.第一行和最后一行无间隔元素
3.中间元素为:当前行+2*(总行数-当前层行)
三、代码:
这里解释一下else以后的那部分,是最主要的地方。
首先,我们用了两层循环i和j。i用来表示哪一层,j用来表示i层中的第几个元素。我们注意到在j循环中,用到了i,length,delta的写法,这样的意思是,从i开始,到length结束,每间隔delta是一个j。其实原本程序是这么写的,下面这个可能看的更清楚一些:
Thestring[code]"PAYPALISHIRING"iswritteninazigzagpatternonagivennumberofrowslikethis:(youmaywanttodisplaythispatterninafixedfontforbetterlegibility)[/code]
PAHN APLSIIG YIR
Andthenreadlinebyline:[code]"PAHNAPLSIIGYIR"
Writethecodethatwilltakeastringandmakethisconversiongivenanumberofrows:
stringconvert(stringtext,intnRows);
convert("PAYPALISHIRING",3)shouldreturn
"PAHNAPLSIIGYIR".[/code]
二、解析
这题是一道找规律的数学题,找到规律后并不难。是要将原字符串按照Z字型排好后,从上到下以此输出元素。直接拿例子来说吧。
先说一下给的例子,写出Z字型的字母和下标,如下图所示。根据下标我们可以看到,其实无论字符串内容是什么,Z型的下标其实都是固定的。因此我们的任务转化成为:找到字符长度和Z层数之间的数学关系。也就是说,以3层为例,我们要输出的顺序是048121357911132610这些位置上对应的字符。
P:0A:4H:8N:12
A:1P:3L:5S:7I:9I:11G:13
Y:2I:6R:10
再画出一个5层的例子,方便对比:
0 8 16
1 791517
2 6 101418
35 111319
4 1220
完整的Z字型是有规律可循的,比如5层中,后面所有的数字都在重复0-8的过程,所以我们来看看哪里可以被我们所用:
1.3层中,第一行为04,5层中,第一行为08,这里我们发现,差值delta=2*(层数-1)。例如在5层中,第0行相同位置0和8相差8,第1行相同位置19相差8。好了,这里我们得打了第一个有用规则。继续往下看。
2.3层中,最后一行为2610,5层中,最后一行为41220,相差为8上面已经得到。统筹的看第一行与最后一行,我们发现这两行的元素是比较整齐的,中间没有插入的元素。所有这两行在做处理的时候,应该归为一类。
3.下面我们看最左边一行,都是0123..代表的是第几层,ok这个很容易
4.剩下最后的也是最复杂的,中间部分。拿5层中第1行为例:1791517,这里面其实有两部分内容。第一部分同第一行和最后一行一样,是比较整洁的元素,如1917,他们之间相差都是8.第二部分就是多出来的7和15,如何求的他们呢?这时我们看第一行1和7相差6,第二行2和6相差4,第三行3和5相差2,这里我们就找到了规律,即:7=1+6=1+2*3,6=2+4=2+2*2,5=3+2=3+2*1。这里,等号左边是我们要通过公式得到的,等号右边第一项是行数,第二项2*n,n就是总行数-当前行数。7(要求的)=1(目前是第一行)+2*3(总行数为4,从0开始-1当前行)。
OK到这里,我们已经找到了所有的规律,总结如下:
1.相同位置差距delta为2*(层数-1)
2.第一行和最后一行无间隔元素
3.中间元素为:当前行+2*(总行数-当前层行)
三、代码:
classSolution:
#@param{string}s
#@param{integer}numRows
#@return{string}
defconvert(self,s,numRows):
length=len(s)
delta=2*(numRows-1)
zigzag_pos=[]
ifnumRows==1orlength<=numRows:
returns
else:
#cratethezigzagpostoindicatetheorderofs
foriinrange(numRows):
forjinrange(i,length,delta):
zigzag_pos.append(j)
if(i!=0)and(i!=numRows-1)and(j+(numRows-i-1)*2<length):
zigzag_pos.append(j+(numRows-i-1)*2)
zigzag_str=[]
foriinzigzag_pos:
zigzag_str.append(s[i])
return''.join(zigzag_str)
这里解释一下else以后的那部分,是最主要的地方。
首先,我们用了两层循环i和j。i用来表示哪一层,j用来表示i层中的第几个元素。我们注意到在j循环中,用到了i,length,delta的写法,这样的意思是,从i开始,到length结束,每间隔delta是一个j。其实原本程序是这么写的,下面这个可能看的更清楚一些:
foriinrange(numRows):
forjinrange(i,length,delta):
if(i==0)or(i==numRows-1):
zigzag_pos.append(j)
else:
7zigzag_pos.append(j)
if(j+(numRows-i-1)*2<length):
zigzag_pos.append(j+(numRows-i-1)*2)
这个是不是更容易看懂些呢?
j循环中,第一个
if(i==0)or(i==numRows-1),是用来处理第一行和最后一行,比较干净的元素的。意思就是,这两行的元素,直接将j添加进list。
else就是中间元素。else后第一句zigzag_pos.append(j),是用来添加那些第一类元素,也是比较干净的,例如1916这种
第二句if(j+(numRows-i-1)*2<length),是用来记录中间元素,仔细看的话就是我们刚才推到出的公式。
由于if..else..中都有一句zigzag_pos.append(j),所以我将他提出来,改了一下判读条件,就成了第一份代码的样子。
三、总结 1.写代码之前一定要想清楚。像这种简单的数学题,一定要理清思路。不能靠乱改代码想着凑出一个正确答案,这样是很浪费时间的。 2.你们可能看到了我把第5题回文给跳过去了,只是因为耽误的时间有点多,想着先练一练手。另外我现在在放暑假哈哈哈,在家好幸福~~
相关文章推荐
- 有向图 & 无向图 环判断
- linux性能监控基础命令
- yum 使用笔记
- linux nginx编译安装以及虚拟主机的配置
- 源码树中添加app应用
- Makefile 知识整理
- js页面操作记录
- ORACLE用SYS登录报ORA-28009:connection as SYS should be as SYSDBA OR SYSOPER解决方法
- Java 增强型的for循环 for each
- Mysql字段类型以及操作
- Masonry简单使用
- 程序员编程的10个实用技巧
- RecyclerView滑动卡顿问题的一种解决方法
- a network-related or instance-specific error occurred while establishing a connection to sql
- android嵌套使用ViewPager和ScrollView焦点冲突解决方案
- 设计模式-单例模式(Singleton Pattern)
- 注册表-注册表被禁用如何处理
- Python package和folder
- C#调用XML格式的webconfig节点
- 通用PE工具箱装系统(V6.3) 安装Ghost版XP、WIN7系统