您的位置:首页 > 其它

Ugly Number

2015-08-31 22:10 197 查看

题目

给一个数判断它是否是丑数。

说明:因子只包含2或3或5的数称作丑数。假定1是丑数。

解题过程

如果给定一个数,判断它是不是丑数很简单,只需依次除以2, 3,5,然后分析最后的结果,就可知道它是不是丑数。

然后还有一个进阶版,就是求丑数序列的第n个丑数。这个听起来似乎很简单的样子,但是其实还暗藏玄机呢。我最开始的思路是依次求出前n个从丑数,这样做的复杂度在O(n²),超过了所规定的时间复杂度。

接着,我试着去想是否可以把时间复杂度降到n,这样就是说前后的丑数是有联系的。然后我试着想方法去找出丑数序列中序号和丑数的对应关系,结果并没有找到。在断断续续地思考过程中,我隐约意识到可能存在着一种由前向后的迭代能够实现在O(n)的复杂度计算出第n个丑数。然后我试图找出计算丑数序列的累乘规律,但是从序列的前端元素来看,似乎很难发现什么规律。

最后我看了看discussion发现支持率较高的java solution中采用了队列,这是一种我并不怎么熟悉的数据结构和类,一开始拿过代码来,整个人就蒙了,根本不理解题目的意思。于是我就去搜索了解队列和LinkedList两种数据结构。查了查他们的主要方法,然后还是不懂它这是在干什么(智商拙计啊),于是我又查了查关于丑数解法的中文解析,才最终明白了它的算法的思想。

总结

java中有很多类和数据结构我都不了解,这对于最初的我来说,去思考这个题的答案确实有些高要求了。当时我有思路涉及到需要很多个2或3或5相乘,但是思路却局限于他们各自的个数,而非在可能的组合结果里挑选出最小值。也许再继续这么想下去最后会贴近于正确的思路,但是同样不知道Java里有queue的类可以用来实现该题。

寻找共性:那么我想,在使用queue结构的应用情境中,他们一定有很多共性。例如丑数这个题,我们维护三个队列:

q2队列中我们只进行*2的操作;

q3队列中只进行*3的操作;

q5队列中只进行*5的操作。

然后我们始终取三个队列中所出现的丑数的最小值,当然这三个队列都是有序队列。当然,还设置了一个变量res用来保存当前的第i个丑数。

这种思路特别像是多线程问题,他们共同在处理一个res的资源。在满足不同的条件下执行不同的操作。要注意到有一点思路很特别。就是之前思考问题,思路都是线性的,也就是单线程吧,不会横向发散,例如采用多队列的思想实现了多线程。

反思

时隔近一年之后,我在总结自己刷leetcode题目的过程。现在已经刷完了67道题,基本easy难度的题自己都能解决出来,但是多数耗时在一小时左右,曾经在网上看到帖子说要想进大公司,easy题目必须刷到能够10-15分钟一道,这说明即便是基础题目,自己和较好的水平仍有较大差距。

在今年六月份全职刷题以后,大约用了一个月的时间刷了60道题,多数题遵循尽量自己想的原则,实在想不出来的话去参考实现discuss的答案。回过头来看丑数2这道题,题目难度是中等类型,用了三个队列,当时刚开始刷题,对leetcode刷题的过程也没啥概念,进度很慢,毫无头绪。

现在发现其实算法设计在很大程度上也依赖于自己对数据结构的掌握程度,只有非常熟练常用的数据结构,才能更好的更熟练的去构思设计基于某些数据结构的算法。

所以应该去「刻意练习」java中的数据结构吗?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode 丑数