JAVA-数据结构-队列-附leetcode
1.简介
排队——先进先出
单端队列—— 只有一个口可以进,一个口可以出
双端队列—— 两个都可以进,两个口都可以出
左进右出 右进左出
时间复杂度
访问 | O(N) |
---|---|
搜索 | O(n) |
插入 | O(1) |
删除 | O(1) |
访问搜索都要从头到尾找
2.JAVA队列基本操作
//创建队列 使用数组构建 添加删除时间复杂度容易变成O(n)
Queue<Integer> queue = new LinkedList<>();
//添加元素 时间复杂度O(1)
queue.add(1);
queue.add(2);
queue.add(3);
System.out.println(queue.toString());
//获取元素 获取即将出队的元素 时间复杂度O(1)
int temp1 = queue.peek();
System.out.println(temp1);
//删除元素 删除即将出队的元素 时间复杂度O(1)
int temp2 = queue.poll();
System.out.println(temp2);
System.out.println(queue.toString());
//判断队列是否为空 时间复杂度O(1)
System.out.println(queue.isEmpty());
//队列长度 时间复杂度O(1)
System.out.println(queue.size());
//遍历队列 时间复杂度O(n)
while (!queue.isEmpty()){
int temp = queue.poll();
System.out.println(temp);
}
3.Leetcode练习题
933 最近的请求次数
class RecentCounter {
private Queue<Integer> pingQueue;
private static final int span = 3000;
public RecentCounter() {
// 双端队列
pingQueue = new LinkedList();
}
public int ping(int t) {
// 队尾插入
pingQueue.add(t);
// 从队头遍历
while (pingQueue.peek() < t - span) {
// 将所有在时间t-3000之前的ping移出队列
pingQueue.poll();
}
// 只考虑最近3000到现在的ping数
return pingQueue.size();
}
}
239 滑动窗口最大值
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums == null || nums.length < 2) return nums;
// 双向队列 保存当前窗口最大值的数组位置 保证队列中数组位置的数值按从大到小排序
LinkedList<Integer> queue = new LinkedList();
// 结果数组
int[] result = new int[nums.length-k+1];
// 遍历nums数组
for(int i = 0;i < nums.length;i++){
// 保证从大到小 如果前面数小则需要依次弹出,直至满足要求
while(!queue.isEmpty() && nums[queue.peekLast()] <= nums[i]){
queue.pollLast();
}
// 添加当前值对应的数组下标
queue.addLast(i);
// 判断当前队列中队首的值是否有效
if(queue.peek() <= i-k){
queue.poll();
}
// 当窗口长度为k时 保存当前窗口中最大值
if(i+1 >= k){
result[i+1-k] = nums[queue.peek()];
}
}
return result;
}
}