1.复杂度
图像描述常见复杂度大小
常见算法的复杂度
###常用数据结构操作的复杂度
各种堆的复杂度
严格斐波那契堆复杂度最小
2.优先队列
题目:返回数据流中第K大的元素
/*
* 使用堆排序(优先队列)解决 输入流中第K的数据
* 注意java中的PriorityQueue便是最小堆 可以直接用
* 堆大小:size() 添加元素:offer() 弹出堆顶元素 pop()
*/
class Kthlargest{
final PriorityQueue<Integer> q;
final int k;
public Kthlargest(int k,int[]a){
this.k=k;
q=new PriorityQueue<>(k);
for(int n:a){
add(n);
}
}
public int add(int n){
if(q.size()<k){
q.offer(n);
}else if(q.peek()<n){
q.poll();
q.offer(n);
}
return q.peek();
}
}
题目:滑动窗口最大值
题目的意思是给一个数组 给一个窗口大小是K 一次向右边滑动一次 记录每一次窗口的最大值
解答:1.使用最大堆 建立一个大小是K的堆 没滑动一次 调整一下堆结构 根节点就是当前节点的最大值
时间复杂度分析:对于数组中每一个元素都有进一次堆:N 在堆中每一次排序时间复杂度都是Klog(K)
所以总共的时间复杂度是N*log(K)
对1的优化:2.使用一个双端队列 这个队列最多可以存放K个元素 当有新元素进来的时候 如果比前面的大 就把前面的踢出去 使用让最大的元素在第一个位置
时间复杂度分析:每个元素进一次队列 是N 在队列中的操作是O(1) 最后总的时间复杂度是N
def maxSlidingWindow(nums,k):
if not nums:return []## nums 是空的话 直接返回
windows,res=[],[]## windows 存放索引 res存放滑动的窗口最大值
for i,x in enumerate(nums):## 得到双端队列的索引 以及对应的数值
if i>=k and windows[0]<=i-k:## 窗口 滑动
windows.pop(0)
while windows and nums[windows[-1]]<x:## 保证windows[0] 最大
windows.pop()
windows.append(i)
if i>=k-1:## 保存当前窗口的最大值
res.append(nums[window[0]])
return res