Python heap/哈希表+最小堆/分割数组为连续子序列

今天的每日一题看的头疼,一看题解,😔哈希表+最小堆???什么玩意儿啊……我的数据结构早就喂狗了啊TT啊啊啊啊w(゚Д゚)w

Anyway,生活还是得继续。

散列表(Hash table,也叫哈希表),是根据关键码值(Key
value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

回忆起了被散列函数支配的恐惧,但这次还好,我们不用自己手写哈希表了,可以直接调用。不用再自己考虑什么存放冲突,散列函数是不是均匀啦!

最小堆,是一种经过排序的完全二叉树,其中任一非终端节点的数据值均不大于其左子节点和右子节点的值。

说人话呢,哈希表 = python dict,最小堆 = python heapq…

为什么要用哈希表+最小堆?

  • 哈希表的查找会比其他数据结构快很多,体现在python代码层面,同样的查找key-value对,如果用dict来实现,会比用两个list,或者tuple的list快。
  • 最小堆在python里不是单独的数据结构,用list来储存东西的时候,也可以调用heapq.heappop(xxx_listname)等指令来对list进行heap的相关操作。换句话说,用heapq的函数等同于不断的对list进行sort,还快。尤其是我们的list大部分是有序的,只要维护很少的无序元素进行下沉就ok了。

总结:哈希表或者最小堆都是在实际写python代码的时候可以用的小技巧,目的都是加速哈。

那么我们来实操一下,今日的力扣题。

  • 分割数组为连续子序列
    给你一个按升序排序的整数数组 num(可能包含重复数字),请你将它们分割成一个或多个子序列,其中每个子序列都由连续整数组成且长度至少为 3 。
    如果可以完成上述分割,则返回 true ;否则,返回 false 。

这道题的思路呢,是遍历这个有序数组,用哈希表储存每个数值作为尾部对应的连续数组数量。
比如123345这个数组,首先从1开始,因为0没作为key存在字典里,默认的value就是个空列表,我们新开一个子序列,连续数组数量就+1,1作为key存在字典里了,value定义成存放长度的堆,现在就是[1],没啥需要维护的,意思是以1为队尾的子序列只有1个,子序列长度为1。
然后到2,1作为key的话,可以调出[1]这个存长度的列表,抽出里面的最小值,加上1(因为把2加到队尾了,长度增加了1)。
然后是第一个3,2作为value可以调出[2],heappop出唯一的独苗苗,现在的字典里不空的列表只剩下{3:[3]}了。
第二个3,2作为value的列表已经空了,那么只能新开一个子序列了。此时字典内非空的列表变成了{3:[1,3]}.
然后是4,注意我们的value是调用heapq来push值进去的,始终保持从小到大的顺序,因为我们要优先让短的子序列变长。所以字典变成{3:[3],4:[2]}
最后一个是5,把4的列表heappop个值出来+1,字典变成{3:[3],5:[3]}.
遍历结束,统计此时字典内非空的列表长度是不是都比3大,是的话就return True,否则就不行return False.

写成代码就尼玛简单

class Solution:
    def isPossible(self, nums: List[int]) -> bool:
        from collections import defaultdict
        subsequence = defaultdict(list)
        for i in nums:
            if last_num_subseq_lens := subsequence[i-1]:
                last_num_shortest_subseq_len = heapq.heappop(last_num_subseq_lens)
                heapq.heappush(subsequence[i],last_num_shortest_subseq_len+1)
            else:
                heapq.heappush(subsequence[i],1)
        for i in nums:
            if subsequence[i] and subsequence[i][0] < 3:
                return False
        return True

啊,事后感觉哈希表和最小堆也不过如此。不用自己写,随便白piao别人的轮子真是太快乐了(●’◡’●)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值