算法岗位之数据结构哈希部分2

  1. Hash表处理冲突的方法
  • 开放定址法
    为产生冲突的地址求得一个地址序列,其中。其中m为表的长度,而增量有三种取值方法,线性探测再散列,平方探测再散列,随机探测再散列。
    注: 平方探测再散列: di = 12, -12, 22, -22
  • 链地址法
    将所有Hash地址相同的记录都链接在同一链表中
  • 再Hash法
    同时构造多个不同的Hash函数,当产生冲突时,计算另一个Hash函数地址直到不再发生冲突为止。
  • 建立公共溢出区
    将Hash表分为基本表和溢出表,若是与基本表发生冲突,都放入溢出表。
  1. 一致性哈希
    先构造一个长度为232的整数环(这个环被称为一致性Hash环),根据服务器节点名称的Hash值(其分布为[0, 232-1])将服务器节点放置在这个Hash环上,然后根据数据的Key值计算得到其Hash值(其分布也为[0, 232-1]),接着在Hash环上顺时针查找距离这个Key值的Hash值最近的服务器节点,完成Key到服务器的映射查找。
    这种算法解决了普通余数Hash算法伸缩性差的问题,可以保证在上线、下线服务器的情况下尽量有多的请求命中原来路由到的服务器。
    参考链接(讲的清楚明白):
    https://zhuanlan.zhihu.com/p/34985026

  2. apriori

  • 支持度和置信度
    支持度(support): 被定义为数据集中包含该项集的记录所占的比例。支持度是针对项集来说的,因此可以定义一个最小支持度,而只保留满足最小支持度的项集。
    置信度(confidence): 假设{尿布, 啤酒}的支持度为3/5,尿布的支持度为4/5,则“尿布 ➞ 啤酒”的可信度为3/4=0.75。简单来说,就是用户购买尿布的事件中包含“购买尿布和啤酒”的比率。这意味着对于包含“尿布”的所有记录,我们的规则对其中75%的记录都适用。

  • 发现频繁项集
    假定事务总数为N,支持度阈值是minsup,发现频繁项集的过程如下(理论上,存在许多产生候选项集的方法,本例使用支持度阈值来产生):
    ①初始时每个项都被看作候选1-项集。计数对它们的支持度之后,将支持度少于阈值的候选项集丢弃,生成频繁1-项集。
    ②在第二次迭代,依据Apriori原理(即所有非频繁的1-项集的超集都是非频繁的),仅使用频繁1-项集来产生候选2-项集。此时生成的候选2-项集有多个,将支持度少于阈值的候选项集丢弃,生成频繁2-项集。
    ③经过多次迭代,每次用上一次生成的频繁n-项集产生新的候选(n+1)-项集,直至没有发现频繁(n+1)-项集,则得到的频繁n-项集就是最终结果。

  • 发现关联规则
    发现关联规则是指找出支持度大于等于minsup并且置信度大于等于minconf的所有规则,其中minsup和minconf是对应的支持度阈值和置信度阈值。

  1. KM算法
  • 匈牙利算法:求最大匹配,那么我们希望每一个在左边的点都尽量找到右边的一个点和它匹配。我们依次枚举左边的点x的所有出边指向的点y,若y之前没有被匹配,那么(x,y)就是一对合法的匹配,我们将匹配数加一,否则我们试图给原来匹配y的x’重新找一个匹配,如果x’匹配成功,那么(x,y)就可以新增为一对合法的匹配。给x’寻找匹配的过程可以递归解决.
    从一边的未饱和点出发,寻找增广路。复杂度:O(VE)
  • KM算法:给定一个带权的二分图,求权值最大的完备匹配
    相等子图的完备匹配=原图的最大权匹配
    1)初始化可行性顶标
    2)对n个点在相等子图中寻找增广路
    (1)初始化访问标记
    (2)寻找增广路
    (3)若增广路不存在,则修改交错路中的顶标,直到对某个点而言找到一条增广路为止
    3)求得最大权
  • 算法时间复杂度O(n3)O(n3)
  1. hashCode() 和equals() 方法的重要性体现在什么地方?
    Java中的HashMap使用hashCode()和equals()方法来确定键值对的索引,当根据键获取值的时候也会用到这两个方法。如果没有正确的实现这两个方法,两个不同的键可能会有相同的hash值,因此,可能会被集合认为是相等的。而且,这两个方法也用来发现重复元素。所以这两个方法的实现对HashMap的精确性和正确性是至关重要的。
  • hashcode()方法:
    得到的地址的映射值(不一定是存放地址).如果hashcode()值相等,则说明存放在同一个桶(链地址法中地址相同的链表)里,再通过equals()方法比较是否是同一个对象.
  • equals()方法:
    equals()是Object的方法比较的是对象的地址, 在Integer、Double、String类中重写equals()方法,比较的是对象的内容.
  • 总结:
  1. hashCode主要用于提升查询效率,来确定在散列结构中对象的存储地址;
  2. 重写equals()必须重写hashCode(),二者参与计算的自身属性字段应该相同;
  3. hash类型的存储结构,添加元素重复性校验的标准就是先取hashCode值,后判断equals();
  4. equals()相等的两个对象,hashcode()一定相等;
    反过来:hashcode()不等,一定能推出equals()也不等;
  5. hashcode()相等,equals()可能相等,也可能不等。
  1. HashMap的工作原理是什么?
    HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象。
  • 当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存entry对象(Map中的一个key-value对实体)。
  • 当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。
  • HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会储存在链表的下一个节点中。 HashMap在每个链表节点中储存键值对对象。
  1. 什么是hashmap?
  • HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
  • HashMap 继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口。
  • HashMap 的实现不是同步的,这意味着它不是线程安全的。它的key、value都可以为null。此外,HashMap中的映射不是有序的。
  • HashMap 的实例有两个参数影响其性能:“初始容量” 和 “加载因子”。容量 是哈希表中桶的数量,初始容量 只是哈希表在创建时的容量。加载因子 是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行 rehash 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。
    通常,默认加载因子是 0.75, 这是在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本(在大多数 HashMap 类的操作中,包括 get 和 put 操作,都反映了这一点)。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少 rehash 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 rehash 操作。
  • hashmap共有4个构造函数:
// 默认构造函数。
HashMap()

// 指定“容量大小”的构造函数
HashMap(int capacity)

// 指定“容量大小”和“加载因子”的构造函数
HashMap(int capacity, float loadFactor)

// 包含“子Map”的构造函数
HashMap(Map<? extends K, ? extends V> map)
  1. hashset 存的数是有序的吗
    无序

  2. Object作为HashMap的key的话,对Object有什么要求吗?
    要求Object中hashcode不能变。如果发生改变,键值在放入时和获取时返回不同的hashcode的话,那么就不能从HashMap中找到你想要的对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值