美文网首页
LintCode 4. 丑数 II

LintCode 4. 丑数 II

作者: CW不要无聊的风格 | 来源:发表于2020-08-05 12:48 被阅读0次

    题目描述

    设计一个算法,找出只含素因子2,3,5 的第 n 小的数。

    符合条件的数如:1, 2, 3, 4, 5, 6, 8, 9, 10, 12...


    测试样例

    输入:9

    输出:10

    输入:1

    输出:1


    解题思路

    说明下题目意思,序列中的数字只能是1、2、3、5的倍数(包含它们自身)。

    1、堆

    每次取出堆中最小的数,然后计算出其2倍、3倍以及5倍数,并加入到堆中,那么第n次取到的堆中最小数即第n小的数。


    2、动态规划

    在方法1中,每次都往堆中加入3个数字,并不知道它们之间的大小,如果我们每次都只加入下一个最小数,那么就可以节省查询最小值消耗的时间。

    用一个有序数组dp记录前n个丑数,可以都初始化为1,因为第一个数必然是1。设置三个指针i2、i3和i5均指向dp中的元素,最小的丑数只可能出现在dp[i2]的2倍、dp[i3]的3倍以及dp[i5]的5倍三者之间。并且通过移动最小丑数对应的指针,就能保证生成的丑数序列是有序的。

    时间复杂度:O(n)。生成一个丑数只需常量时间,所以生成n个丑数需要O(n)。

    空间复杂度:O(n)。dp数组的长度为n。


    代码

    1、堆

    import heapq

    class Solution:

        """

        @param n: An integer

        @return: return a  integer as description.

        """

        def nthUglyNumber(self, n):

            # write your code here

            nums = [1]

            visited = set([1])

            # min_val是当前堆中最小的数

            # 总共弹出n - 1次

            for count in range(n - 1):

                min_val = heapq.heappop(nums)

                # 序列中的每个数都是其中某个数的2、3或5倍

                for factor in (2, 3, 5):

                    if factor * min_val not in visited:

                        visited.add(factor * min_val)

                        heapq.heappush(nums, factor * min_val)

            # 最后再弹出一次即第n小的数

            return heapq.heappop(nums)

    2、动态规划

    class Solution:

        """

        @param n: An integer

        @return: return a  integer as description.

        """

        def nthUglyNumber(self, n):

            # write your code here

            dp = [1] * n

            i2 = i3 = i5 = 0

            for i in range(1, n):

                # 序列中每个数(除1外)肯定是其中某个数的2、3或5倍

                # 每次都取下一个最小的丑数加入序列,同时移动对应的指针

                dp[i] = min(2 * dp[i2], 3 * dp[i3], 5 * dp[i5])

                if dp[i] == 2 * dp[i2]:

                    i2 += 1

                if dp[i] == 3 * dp[i3]:

                    i3 += 1

                if dp[i] == 5 * dp[i5]:

                    i5 += 1

            return dp[n - 1]

    相关文章

      网友评论

          本文标题:LintCode 4. 丑数 II

          本文链接:https://www.haomeiwen.com/subject/zfinrktx.html