1.622.设计循环队列
⛱️试题链接戳这里!
🍉精华思路
这道题最精髓的点是,如何让队列“循环”起来?
——取模!
🌴深度剖析
1️⃣循环队列的特征
1 空间大小是固定的
2 空间重复使用
3 先进先出
2️⃣如何区分循环队列的空和满?
在现有的基础上,队列空和满时tail==head,无法区分,因此我们需要另寻他法。
方法一:增加一个额外的空间
队列为空时:head==tail
队列为满时:tail的后一个为head(注意:这里规定tail指向尾元素的下一个位置)
这里直接写tail+1==head显然是错的,比如下面的情况:
所以我们得考虑一下如何让它回绕回最前面去。
[tail+1]%(N+1)==head(注:这里的N指可用的空间)
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->tail+1)%(obj->k+1)==obj->head;
}
这样就可以解决问题了。
3️⃣求队尾元素
由于我们的tail指向的是尾元素的后一个,所以我们求队尾元素时应该向前找
这时会存在两种情况:
obj->tail==0?obj->k:obj->tail-1
int myCircularQueueRear(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))return -1;
return obj->a[(obj->tail-1+obj->k+1)%(obj->k+1)];
}
注意此时空间有k+1个,tail和head在进行回绕时,应当是%(obj->k+1)
方法二:循环体中增加一个size指标
初始化时置为0
增加元素 obj->size++
减少元素 obj->size--
空判断 obj->size==0
满判断 obj->size==k
注意此时空间只有k个,tail和head在进行回绕时,应当是%obj->k
🥳代码实现
方法一:增加一个额外的空间
typedef struct {
int* a;
int head;//指向头
int tail;//指向尾的下一个
int k;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
obj->a=(int*)malloc(sizeof(int)*(k+1));//多开一个,防止溢出
obj->head=obj->tail=0;
obj->k=k;
return obj;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->head==obj->tail;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->tail+1)%(obj->k+1)==obj->head;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if(myCircularQueueIsFull(obj))return false;
obj->a[obj->tail]=value;
obj->tail++;
obj->tail=(obj->tail)%(obj->k+1);
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))return false;
obj->head++;
obj->head=(obj->head)%(obj->k+1);
return true;
}
int myCircularQueueFront(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))return -1;
return obj->a[obj->head];
}
int myCircularQueueRear(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))return -1;
return obj->a[(obj->tail-1+obj->k+1)%(obj->k+1)];
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
obj->a=NULL;
free(obj);
}
/**
* Your MyCircularQueue struct will be instantiated and called as such:
* MyCircularQueue* obj = myCircularQueueCreate(k);
* bool param_1 = myCircularQueueEnQueue(obj, value);
* bool param_2 = myCircularQueueDeQueue(obj);
* int param_3 = myCircularQueueFront(obj);
* int param_4 = myCircularQueueRear(obj);
* bool param_5 = myCircularQueueIsEmpty(obj);
* bool param_6 = myCircularQueueIsFull(obj);
* myCircularQueueFree(obj);
*/
方法二:循环体中增加一个size指标
typedef struct {
int* a;
int head;
int tail;
int k;
int size;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
obj->a=(int*)malloc(sizeof(int)*k);
obj->head=obj->tail=0;
obj->k=k;
obj->size=0;
return obj;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->size==0;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return obj->size==obj->k;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if(myCircularQueueIsFull(obj))return false;
obj->a[obj->tail]=value;
obj->tail++;
obj->tail=(obj->tail)%(obj->k);
obj->size++;
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))return false;
obj->head++;
obj->head=(obj->head)%(obj->k);
obj->size--;
return true;
}
int myCircularQueueFront(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))return -1;
return obj->a[obj->head];
}
int myCircularQueueRear(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))return -1;
return obj->a[obj->tail==0?obj->k-1:obj->tail-1];
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
obj->a=NULL;
free(obj);
}
/**
* Your MyCircularQueue struct will be instantiated and called as such:
* MyCircularQueue* obj = myCircularQueueCreate(k);
* bool param_1 = myCircularQueueEnQueue(obj, value);
* bool param_2 = myCircularQueueDeQueue(obj);
* int param_3 = myCircularQueueFront(obj);
* int param_4 = myCircularQueueRear(obj);
* bool param_5 = myCircularQueueIsEmpty(obj);
* bool param_6 = myCircularQueueIsFull(obj);
* myCircularQueueFree(obj);
*/