「携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情」
今天我们来做一下和昨天的1201. 丑数 III名字类似的一个题目(实际做法完全不同🤣)
题目链接在这里313. 超级丑数
题意
如果你做过264. 丑数 II,这道题的意思你很快就明白了,这道题只是把三个质数扩展到了若干个。
下面会介绍一个普适的做法,可以同时解决这两道题目。
思路
根据丑数定义我们知道:第一个丑数是1,后面的丑数都是前面的丑数乘以给出的质数得到的。 因为每个丑数都是前面的一个丑数乘以某个质数得到的,我们可以把乘以每个质数生成的丑数序列 列出来,如下: 假如n=12 primes = [2,7,13,19]
所有通过乘以2生成的丑数 1 -> 2*1 -> 2*2 -> 2*4 -> 2*7
所有通过乘以7生成的丑数 1 -> 7*1 -> 7*2 -> 7*4 -> 7*7
所有通过乘以13生成的丑数 1 -> 13*1 -> 13*2 -> 13*4 -> 13*7
所有通过乘以19生成的丑数 1 -> 19*1 -> 19*2 -> 19*4 -> 7*7
data 1 2 4 7 8 14
生成上面的序列之后,可以发现将三个序列从左到右进行归并时,生成的序列就是最终的丑数序列,而我们需要返回的是丑数序列中的第n个。
- 既然是归并过程,而且这里由于丑数个数不确定,所以是多路归并,
- 方法就是为每个序列生成一个指针,指向当前序列下一个需要对比的元素。
- 然后,每一轮开始先取出每个序列指针指向元素的最小值。
- 再将最小值对应序列的指针向后挪动一位,表示下一个会生成的数字,当然这里最小值可能存在重复,所以需要遍历所有的序列来判断。
- 在每一轮结束将当前生成的数字放到data中记录下来,便于下一轮根据指针可以拿到上个丑数
代码实现
结束语
如果有更好的分析思路,欢迎大家在评论区发表看法!⛄