1.队列与堆学习笔记
- 队列的存储结构:
是一种先进先出的线性表,只允许在一端插入数据(队尾),在另一端进行删除操作(队头)
- 头指针 front 和 尾指针 rear
Front(队头):从队列中获得最前面的元素。
Rear(队尾):从队列中获得最后面的元素。
- 队列的操作
Enqueue(入队/插入):添加元素到队列中。如果队列满了,则表示溢出(Overflow)情况。
Dequeue(出队/删除):从队列中剔除元素。该元素被压出(pop)的顺序与push(压入)的顺序一样。如果队列是空的,则表示下溢(underflow)情况。
队列初始条件:队头指针=队尾指针=0
队列满条件:队尾指针=m(设队列当前容量为m)
队列空条件:队头指针=队尾指针
- 堆
利用完全二叉树的结构来实现的一种数据结构,时间复杂度在O(1)~O(logn),堆的落地实现是数组。
完全二叉树不清楚的小伙伴请看这篇文章:https://www.cnblogs.com/myjavascript/articles/4092746.html
堆中某个节点的值总是不大于或者不小于其父节点的值,将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
注意:堆内的元素并不一定数组下标顺序来排序的!
请看堆排序的代码:(这是以前学堆时写的)
//堆排序(大根堆)
void HeapInsert(int *A,int len)
{
if(A==NULL*&&len<2)
{
return;
}
for(int i=0;i<len;i++)
{
heapInsert(A,i);
}
int heapSize=len;
swap(A,0,--heapSize);
while(heapSize>0)
{
heapify(A,0,heapSize);
swap(A,0,--heapSize);
}
}
void heapInsert(int *A,int index)
{
while(A[index]>A[(index-1)/2])
{
swap(A,index,(index-1)/2);
index=(index-1)/2;
}
}
void heapify(int *A,int index,int heapSize)
{
int left=index*2+1;
while(left<heapSize){
int largest=left+1<heapSize&&A[left+1]>A[left]?left+1:left;
largest=A[index]>A[largest]?index:largest;
if(index==largest)
break;
swap(A,index,largest);
index=largest;
left=index*2+1;
}
}
- 参考:
1.https://www.cnblogs.com/JVxie/p/4859889.html
2.https://www.cnblogs.com/helloworld-c/p/4854463.html 密码:abcd111
2.总结:
这两天学习了哈希思想与链表的操作,虽然题难度一般,但使用的知识点挺多的,可见训练营的组织者相当用心。我使用了map和set做了第一天的题;使用快慢指针和map做了第二天的题;虽然自己的编程水平目前很一般,但在逐渐养成习惯。
3.LeetCode第239题
题意是:给出一个可能包含重复的整数数组,和一个大小为 k 的滑动窗口, 从左到右在数组中滑动这个窗口,找到数组中每个窗口内的最大值。
最开始想的是从开始位置i,逐个遍历;j=i;i=i+k;找到最大值,两层循环,发现这样时间复杂度有些大;
于是绞尽脑汁想,想用队列来做,无奈没做出来,参考了这个人的方法,用的是双端队列。
借助一个辅助队列(双端队列),从头遍历数组,根据如下规则进行入队列或出队列操作:
- 1. 如果队列为空,则当前数字入队列
- 2. 如果当前数字大于队列尾,则删除队列尾,直到当前数字小于等于队列尾,或者队列空,然后当前数字入队列
- 3. 如果当前数字小于队列尾,则当前数字入队列
- 4. 如果队列头超出滑动窗口范围,则删除队列头
这样能始终保证队列头为当前的最大值
使用C++编程实现:
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> res;
int n=nums.size();
if(n==0||k>n)
return res;
deque<int> myQueue;
for(int i=0;i<n;i++)
{
if(!myQueue.empty())
{
if(i>=myQueue.front()+k)
myQueue.pop_front();
while(!myQueue.empty()&&nums[i]>=nums[myQueue.back()])
myQueue.pop_back();
}
myQueue.push_back(i);
if(i+1>=k)
res.push_back(nums[myQueue.front()]);
}
return res;
}
};
参考: