当前位置 博文首页 > 峰峰的猫的博客:查找之哈希表(python实现LeetCode刷题)

    峰峰的猫的博客:查找之哈希表(python实现LeetCode刷题)

    作者:[db:作者] 时间:2021-09-03 18:16

    根据数据结构书上的讲解,查找包括暴力遍历、折半查找以及二叉树查找。其中顺序查找和折半查找适合静态查找,折半查找前提线性表必须是有序的。三种查找算法的时间复杂度分别是 O ( n ) , O ( l o g n ) , O ( l o g n ) O(n),O(logn),O(logn) O(n),O(logn),O(logn)。线性表和树表都是通过比较关键字的方法,查找的效率取决于关键字的次数。有没有一种方法可以不进行关键字比较,直接找到目标?那就是散列表的查找,也称哈希表。是通过散列函数将关键字映射到存储地址,建立了关键字和存储地址的一种直接映射关系。

    • 哈希表包括哈希函数,处理冲突的方法和查找性能等三个方面。

    这里主要讲解python中dict使用的哈希表,最低能在 O ( 1 ) O(1) O(1)时间内完成搜索!python中dict在处理冲突的时候采用的是开放寻址法,开放寻址法是在线性存储空间上的解决方案,也称为闭散列。当发生冲突时,采用冲突处理方法在线性存储空间上探测其他位置: h a s h , ( k e y ) = ( h a s h ( k e y ) + d i ) hash^,(key) = (hash(key)+d_i)%m hash,(key)=(hash(key)+di?)
    开放寻址法又分为线性探测法、二次探测法、随机探测法和再散法。

    开放寻址法

    • 线性探测法
      线性探测法是最简单的开发地址法,线性探测的 d i d_i di?每次增加1,即:
      d i d_i di? = 1,…,m-1。
      线性探测法比较简单,只要有空间就会一直探测直到探测到位置为止。但是处理冲突的过程中,会出现非同义词对同一个散列地址争夺的现象,称为“堆积”。
    • 二次探测法
      二次探测法采用前后跳跃式探测的方法,即以增量平方的形式进行探测,避免堆积。增量序列如下:
      d i = 1 2 , ? 1 2 , 2 2 , ? 2 2 , . . . k 2 , ? k 2 ( k &lt; = m / 2 ) d_i = 1^2,-1^2,2^2,-2^2,...k^2,-k^2(k&lt;=m/2) di?=12,?1222,?22...k2,?k2(k<=m/2)
      注意:二次探测法是跳跃式探测,效率较高,但是会出现有存储空间但是探测不到的情况,因而存储失败,而线性探测是只要有空间就一定能够探测成功。
    • 随机探测法
      采用伪随机数进行探测,利用伪随机数避免堆积。随机探测的增量序列为:
      d i = d_i= di?=伪随机序列
    • 再散列法
      当通过散列函数得到的地址发生冲突时,再利用第二个散列函数处理,称为双散列法。其增量序列为: d i = h a s h 2 ( k e y ) d_i = hash_2(key) di?=hash2?(key)

    注意:开放地址法处理冲突时,不能随便删除表中的元素,若删除元素会截断其他后续元素的查找。因为在查找过程中,遇到空就会返回查找失败,因此要删除一个元素式,可以做一个删除标记,表示该元素已经删除。

    LeetCode刷题

    该题链接:https://leetcode-cn.com/problems/contains-duplicate/

    class Solution:
        def containsDuplicate(self, nums: List[int]) -> bool:
            t_dict = {}
            for num in nums:
                if num not in t_dict.keys():
                    t_dict[num] = 1
                else:
                    return True
            return False
    
    cs
    下一篇:没有了