1.题目描述:
求一组数组中的第K大或者第k小的数
2.算法:
上一期我们通过了二叉堆来进行该问题的求解,非常的高效,我们通过O(n)就可以解决问题
这一期我们通过SBT来解决:
SBT详解
我们通过SBT的select来解决问题会变得非常高效,如果不考虑剑术的时间,时间复杂度是O(logn),如果考虑建树是O(logn+n*logn)
附上select函数代码:
int SBT::select(int& p,int k) //选择第k大的元素
{
if(size[left[p]]+1==k) return p;
else
{
if(size[left[p]]+1<k) return select(right[p],k-size[left[p]]-1);
else return select(left[p],k);
}
}
SBT正因为有了size域,所以说在查找该问题方面会变的非常的快
当然这是查找第k小问题
如果是查找第k大问题,我们只要用O(1)求出数组长度
再用O(1):length-k就可以了,问题是没有变化的
一般的时候,我们都是不会考虑建树的时间的,这样的情况下,SBT的查找效率明显快于堆的操作