- 建立反向索引表
- 建立比较器
- 核心在于各种结构相互配合
- 最大线段重合问题
- 题目详细
- 每一个线段的开始和结束位置都是整数
- 重合区域长度大于等于1才叫重合
- 返回一个重合区域,使区域上的重合线段数量最多是多少
- 第一种暴力
- 先找最小的开始位置和最大的结束位置
- 考察这个区域上的每一个点5,因为一个重合区域必然包含一个点5
- 算出每一个点5的位置被多少的线段覆盖,取最大值
- 复杂度是(max - min) * N,受制于max-min
- 好办法
- 根据开始位置从小到大将所有线段排序
- 准备一个小根堆
- 从排好序的数组种依此取出线段
- 看这个线段的开始,小根堆种弹出比这个开始小于等于的数
- 看这个线段的结束,小根堆中压入这个结束
- 记录当前堆中留下的数的个数
- 含义是以当前线段的开始为左边界,越过这里的有几条线段
- 记录下的留下的数的个数中最大的那个就是答案
- 关于理解
- 每一个重合部分的左边界,都是某个线段的左边界
- 题目详细
面试中的数据量限制
- 一般c++给1-2s
- java给2-4s
- 指的是代码条数在108-109,一般控制指令条数在108
加强堆
- 对于一个堆来说,如果改变堆中某一个位置的值,这个堆就变成了无效堆
- 如果这个值比原来大,应该要heapify,如果比原来小,应该要heapinsert
- 但是系统实现的堆不支持这种操作
- 系统不能高效的完成这样的操作,是因为系统建立的堆没有反向索引表
- 数组本身代表一张索引表,从下标索引到存储的元素
- 但是不能从元素映射回下标位置,只能遍历找到修改了值的那个元素
- 自己加反向索引表就能做到logN的代价
- c++委员会会提供带反向索引的堆,但偏实用的包中不会提供
- 反向索引表的写法,在堆中增加一个hashmap,indexMap
- arryList的get和set是O(1)复杂度
- 目前的模板是非基础类型,有基础类型需求就要包一层,这是hashmap的设计原因
- 将反向索引表的修改直接封装到交换操作里,保证反向索引表与动态数组同步
- 弹出的时候要反向索引表删除这个弹出的值,压入的时候反向索引表也要增加这个值
- 修改了某一个值就是顺序进行heapInsert,heapify,因为值要么变大要么变小,实际上只会执行二者之一,logn就能完成修改某一个值,非常高效
- 还可以实现高效的删除某一个值,系统只能删除堆顶
- 首先找到这个要删除的值在哪里
- 然后用堆最后一个元素与这个值进行交换,删掉最后一个,替换后的位置上顺序进行heapInsert,heapify