常用低复杂度算法和数据结构
1.查找无序序列中第K大的数:
快速选择算法 O(n) -> O(n*n)。
随机快速选择 O(n)
topK
如果可以一次读取到内存:快速选择,随机快速选择
如果不能一次性读取到内存 使用堆,堆里的节点就是当前已知的topK(O(NlogK)):
- 找到最大的k个数:小根堆
- 找到最小的k个数:大根堆
2.找到序列中的逆序对:
线段树 O(nlogn)
归并排序 O(nlogn)
3.查找序列中的最长递增/递减子序列:
输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
贪心算法+二分查找 O(nlogn)
并且在遍历到数组中每一个元素时,都可以求出到该元素(包含该元素)的最长递增子序列。
4.查找2个序列的最长公共子序列:
输入:text1 = "abcde", text2 = "agcafe"
输出:3
解释:最长公共子序列是 "ace" ,它的长度为 3 。
如果某个序列不包含重复元素,比如text1不包含重复元素,此题可以转成第3题 O(nlogn):
- 将text2中的元素,改成该元素对应得在text1中得索引,text1中没有得元素则不处理,处理完成后text2 = 0204。
- 则该问题转成了求text2得最长递增子序列。
如果2个序列都可能包含重复元素,则只能使用dp算法 O(n*n)
5.多个有序序列合并成一个有序序列
优先队列 O(nlogk): k是有序序列数目,n是序列总得元素和。
6.对链表排序
遍历链表,转成数组,然后使用排序函数,最后再将排序后得数组,转成链表。
7.给定一系列区间,在线求出区间最值。
倍增 O(nlogn)预处理 O(1)查出结果
8.最近公共祖先
- 倍增 O(nlogn)
9.字符串hash
将字符串映射成一个数值,这样在比较两字符串是否相等时,只需要O(1)的时间复杂度。
映射方式:
- 在字符串长度比较长,并且包含的字符较多时,一个64位的整数都无法保存一个字符串时,可以将该字符串映射位131进制数,然后mod 2^64 后的整数作为该字符串的表示。
10.图和树的单源最短路径
1.节点之间的距离是相同的:BFS O(m)
2.节点距离为0-1:双端队列优化BFS O(m)
2.节点数目大于边数目:bellman-ford O(nm)或者使用队列改进bellman-ford
3.边数目大于节点数目:dijkstar O(n*n)或者使用优先级队列改进dijkstar O(mlogm)
11.求pow(x,n)
快速幂 o(logN)
12.树的最近公共祖先
后序遍历(递归)o(n)
13.判断链表是否有环,和入环的节点
快慢指针 o(n)
14.最小生成树
1.prim O(n*n)
2.krustal O(mlogm)
15.区间加减
1.线段树 O(nlogn)
2.差分+前缀和 O(n)
16.找到数组中唯一出现奇数次的元素
异或运算 时间O(n) 空间O(1)
17.DP对字符串预处理
可以快速查找我们需要的东西