用python做算法题的一些小技巧

heapq

a[k] <= a[2k+1] and a[k] <= a[2k+2],(k从0开始),则这个列表是小顶堆(不存在的元素被视为无限大)
heapq库是python自带的最小堆实现
常用方法:

  1. heapq.heappush(heap,item)
    当插入一个元素时,该方法会自动调堆中元素的位置。
  • 比如插入一个比堆顶还小的元素,则新加入的节点会依次向父节点进行比较,然后调整位置直到堆顶。
    在这里插入图片描述
  • 需要注意的是,这个方法不会调整其他节点的元素位置(即不能调整其他节点满足父节点的值大于孩子节点的值),如下图
    在这里插入图片描述
    上图可以看出,该方法只是对新加入节点到堆顶路径的元素进行了操作。

2.heapq.heappop(heap)
弹出并返回堆中的最小值,保持堆不变。如果堆是空的,会引起IndexError异常。如果想获得最小值而不是弹出它,则使用heap[0]

  1. heapq.heappushpop(heap, item)
    先压item入堆,然后弹出堆里最小的元素。
    这个组合比先 heappush(heap,item) 然后再heappop(heap) 效率高。

  2. heapq.heapify(x)
    把列表x转换成一个堆,就地转换,只用线性时间

  3. heapq.heapreplace(heap,item)
    先弹出堆里的最小值,然后压入item。
    (其实更推荐用heappushpop(heap,item),因为这样才能保证返回值是最小的)

  4. 一个典型的堆排序可以这样做

>>> def heapsort(iterable):
...     h = []
...     for value in iterable:
...         heappush(h, value)
...     return [heappop(h) for i in range(len(h))]
...
>>> heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

堆排序可以用于任务优先级排序

>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (7, 'release product'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
>>> heappop(h)
(1, 'write spec')

可是,如果有两个以上事件优先级相同呢?这时该怎么办呢?
可以在优先级后面加一个entry_counts表示进入时的计数值。因为没有两个任务是同时进入的,总有顺序,所以在判断了优先级之后,可以再判断entry_counts以区分相同优先级事件,这样可以让同一优先级下,先加入的任务,先被执行。

bisect

bisect库是python自带的二分查找(边界情况也已经考虑得很好了)
一下是一些方法地操作

  1. bisect.bisect_left(a, x, lo=0, hi=len(a))
    返回应该插入的最左(如果有相同的元素)的下标位置
  2. bisect.bisect_right(a, x, lo=0, hi=len(a))
    在这里插入图片描述
    等价bisect = bisect_right(bisect.py源码最后两行有明确写)
    返回应该插入的最右(如果有相同的元素)的下标位
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值