查找之哈希表(python实现LeetCode刷题)

根据数据结构书上的讲解,查找包括暴力遍历、折半查找以及二叉树查找。其中顺序查找和折半查找适合静态查找,折半查找前提线性表必须是有序的。三种查找算法的时间复杂度分别是 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

猜你喜欢

转载自blog.csdn.net/weixin_42662358/article/details/100531905