lintcode丑数 II

本文探讨了三种高效算法来寻找第N个丑数,即只包含质因数2、3和5的正整数。通过优化计算过程,避免重复计算,使用堆数据结构加速搜索,实现了算法效率的显著提升。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用已有丑数乘以2,3,5寻找丑数。

import time
class Solution:
    """
    @param n: An integer
    @return: return a  integer as description.
    """

    def nthUglyNumber(self, n):
        if n <= 6:
            return n
        list1 = [1, 2, 3, 4, 5, 6]
        i = 6

        while i < n:
            unlist = []
            list2 = [2 * i for i in list1]
            list3 = [3 * i for i in list1]
            list5 = [5 * i for i in list1]
            listsum = sorted(list(set(list2 + list3 + list5)))

            print('listsum =', listsum)
            print("list1 =", list1)

            for item in listsum:
                if item not in list1:
                    print('item =',item)
                    list1.append(item)
                    break
            print("list1 =",list1)

            print('unlist =', unlist)
            i += 1
        return  list1[-1]



a = Solution()
n = 599
start_time = time.time()
print(a.nthUglyNumber(n))
end_time = time.time()
print('共用时:',end_time - start_time)

------------------------------------------------------------
2457600
共用时: 9.42122220993042

缺点:重复计算了所有的丑数乘以2,3,5。乘过2,3,5且放入丑数列表后,以后就不用再计算。

import time
class Solution:
    """
    @param n: An integer
    @return: return a  integer as description.
    """

    def nthUglyNumber(self, n):
        ugly_list = [1]
        p1, p2, p3 = 0, 0, 0
        for i in range(n - 1):
            v1 = ugly_list[p1] * 2
            v2 = ugly_list[p2] * 3
            v3 = ugly_list[p3] * 5
            vmin = min(v1,v2,v3)
            if vmin == v1:
                p1 += 1
            if vmin == v2:
                p2 += 1
            if vmin == v3:
                p3 += 1
            ugly_list.append(vmin)
            print(ugly_list)
        return ugly_list[-1]

a = Solution()
n = 599
start_time = time.time()
print(a.nthUglyNumber(n))
end_time = time.time()
print('共用时:',end_time - start_time)
--------------------------------------------------------
2457600
共用时: 0.6875059604644775

参考:https://www.jiuzhang.com/solution/ugly-number-ii/#tag-other-lang-python
每次只需计算三个数,再比较大小,就可以得到一个丑数。速度快很多。


不用下标记录2,3,5乘到哪那一位。每一位都乘,set去重,然后添加到丑数列表中。

import heapq

class Solution:
    """
    @param {int} n an integer.
    @return {int} the nth prime number as description.
    """
    def nthUglyNumber(self, n):
        heap = [1]
        visited = set([1])
        
        val = None
        for i in range(n):
            val = heapq.heappop(heap)
            for factor in [2, 3, 5]:
                if val * factor not in visited:
                    visited.add(val * factor)
                    heapq.heappush(heap, val * factor)  
        return val

a = Solution()
n = 599
start_time = time.time()
print(a.nthUglyNumber(n))
end_time = time.time()
print('共用时:',end_time - start_time)
——————————————————————————————————————————————————————————————————————————
2457600
共用时: 0.0

https://www.jiuzhang.com/solution/ugly-number-ii/#tag-highlight-lang-python
笔记:

堆是一种特殊的数据结构,它的通常的表示是它的根结点的值最大或者是最小。

python中heapq的使用

列出一些常见的用法:

heap = []#建立一个常见的堆

heappush(heap,item)#往堆中插入一条新的值

item = heappop(heap)#弹出最小的值

item = heap[0]#查看堆中最小的值,不弹出

heapify(x)#以线性时间将一个列表转为堆

item = heapreplace(heap,item)#弹出一个最小的值,然后将item插入到堆当中。堆的整体的结构不会发生改变。
heappoppush()#弹出最小的值,并且将新的值插入其中

merge()#将多个堆进行合并

nlargest(n , iterbale, key=None)从堆中找出做大的N个数,key的作用和sorted( )方法里面的key类似,用列表元素的某个属性和函数作为关键字
https://www.cnblogs.com/chang1203/p/6537345.html

笔记

查找最大或最小的N个元素

怎么样从一个列表中取出最大或最小的N个元素的列表?在Python的标准库中,有一个名为heapq的,该模块中具有两个函数nlargest和nsmallest可以完全解决我们的问题,下面我们来看看这两个函数的作用:

import heapq

L = [5, 4, 6, 2, 8, 10, 1]

获取列表中最大的三个元素

print heapq.nlargest(3, L)

获取列表中最小的三个元素

print heapq.nsmallest(3, L)

=打印结果如下=

[10, 8, 6]
[1, 2, 4]

1
2
3
4
5
6
7
8
9
10
11
12

两个函数都可以传递参数,用于更复杂的数据结构当中:

import heapq

info_list = [
{“name”: “laozhang”, “age”: 20, “score”: 90},
{“name”: “laoli”, “age”: 21, “score”: 88},
{“name”: “laowang”, “age”: 24, “score”: 58},
{“name”: “laohe”, “age”: 22, “score”: 77},
{“name”: “laoyang”, “age”: 21, “score”: 89}
]

取出年龄最大的两个数据

print heapq.nlargest(2, info_list, key=lambda item: item[“age”])

=打印结果如下=

[{‘name’: ‘laowang’, ‘age’: 24, ‘score’: 58}, {‘name’: ‘laohe’, ‘age’: 22, ‘score’: 77}]

作者:奔跑的豆子_
来源:优快云
原文:https://blog.youkuaiyun.com/y472360651/article/details/80725355
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值