有序结构:SortedContainers
有序容器(List/Set/Dict)
Python中的SortedContainerPython中的SortedContainers类似于Java中的Treemap/Treeset,帮你打理好了O(logn)的写查删。
SortedSet:有序集合
SortedDict:有序字典
SortedList:可以看成允许重复元素的OrderedSet。
如果不能用类似的库,要么就要手撸平衡二叉树,要么就只能用List结合bisect来进行写查删。不过记住在List中很多操作受到插入和删除的机能,只能做到O(n)的时间复杂度:比如bisect.insort(List, x)和list.remove(x)。
二叉树简单实现(不含自平衡)
这里我们跳过自平衡。假设自平衡已经实现了(比如用红黑树),那么主要功能和时间复杂度是:
insert(val):O(logN)插入一个元素 实现:从根开始根据val的大小遍历,并在第一个空位新建一个节点delete(val):O(logN)删除一个元素 [LC 450] 实现:从根开始根据val的大小遍历。三种情况:不存在,则返回
存在,没有左儿子或者右儿子,用左儿子或右儿子或None代替自己。
存在,有左儿子和右儿子,用右儿子代替自己。同时把左儿子插到右儿子的最小节点(leftmost node)的左边。
findMin():O(logN)找到最小值 实现:返回最左边的节点值findMax():O(logN)找到最大值 实现:返回最右边的节点值
参考代码(维护一个长度为k的有序数组):
除了用前缀和把二维区域和转化成一维数组,这道题的本质是在一位数组中求连续和<=k的最大值。用一位数组s[i]表示前缀和之后,问题就是:
用有序集合来存储之前看到的s[i],就能用O(nlogn)的算法枚举s[j]二分查找s[i]。
参考代码:
例题:考场就座 [LC855]
延伸阅读:Urinal protocol vulnerability
参考代码:
例题:寻找右区间
参考代码:
Last updated
Was this helpful?