刷爆leetcode第八期

简介: 刷爆leetcode第八期

题目一 设计循环队列

题目分析

这里直接看图

我们发现这里要求我们设计一个循环队列

这要怎么设计呢?

还是一样 我们先画图

我们首先假设只能储存四个数字

同学们看这张图能观察到什么呢?

是不是可以得到front 和 rear相等的时候整个队列为空

这里当插入一个数据之后 rear就往后走了一步

我们插入四个数据试试

咦 这个时候front和rear又相等了

这里好像队列满的条件和队列空的条件一样了

那么这个时候有没有什么好办法可以区分两种相等呢?

好像没有特别好的方法

那么我们加一个空数据

这样子可不可以呢?

这个时候呢?

我们好像可以使用公式

(tail+1)% (k+1) == head

来判断是否为满

这不就形成循环了嘛

那么我们接下来开始看题目、

第一步 设计结构体

typedef struct {
    int*a;
    int front;
    int rear;
    int k;
} MyCircularQueue;

我们需要用到的数据有

数组 头指针 尾指针 数字K

所以说我们定义这几个变量出来

第二步 初始化结构体

1 首先我们先动态开辟结构体的内存

2 因为需要k+1个数据的存贮空间 所以我们要开辟k+1个内存的大小

3 开始的头尾指针都设置为0

MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue*obj =(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    obj->a = (int*)malloc(sizeof(int)*(k+1));
    obj->front = obj->rear = 0;
    obj->k = k;
    return obj;
}

第三步 我们先判断队列是否空或满

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    return obj->front == obj->rear;
}
 
bool myCircularQueueIsFull(MyCircularQueue* obj) {
    return (obj->rear+1)%(obj->k+1)==obj->front;

判断满的情况我们就可以用公式啦

我们说有以上代码可以来判断

第四步 重新回到插入数据

这里主要分两种情况讨论

像这种情况 直接插入 rear+1就可以

但是如果是这样子呢?

像这个时候tail就要走到最前面了?

那么我们怎么来表示呢?

我们说

可以使用 tail=(tail+1)%(k+1)表示 想想看 是不是这样子

当tail等于4向前是不是就变成0了

所以我们开始敲代码

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if(myCircularQueueIsFull(obj))
    return false;
    obj->a[obj->rear++] = value;
    obj->rear%=(obj->k+1);
    return true;
}

这样子就完成了

第五步 删除数据

这个的判断和前面一样

参考前面的代码就能够写出来了

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    return false;
    ++obj->front;
     obj->front%=(obj->k+1);
     return true;
}

第六步 返回头数据

int myCircularQueueFront(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    return -1;
 
    return obj->a[obj->front];
}

这个很简单 返回头部的数据就可以

数组越界问题跟前面的处理结果相似

第七步 返回尾数据

这里要考虑一个特殊情况

就是当尾指针在数组的0位置的时候

这个时候我们单拎出来分类讨论就可以

如果是0的话 我们返回最后面的数据就可以

int myCircularQueueRear(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    return -1;
 
    if(obj->rear==0)
    {
        return obj->a[obj->k];
    }else
    {
        return obj->a[obj->rear-1];
    }
}

第八步 释放

这个也很简单,先释放结构里面的再释放结构体

void myCircularQueueFree(MyCircularQueue* obj) {
    free(obj->a);
    free(obj);
}

源码

1. ttypedef struct {
    int*a;
    int front;
    int rear;
    int k;
} MyCircularQueue;
 
 
MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue*obj =(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    obj->a = (int*)malloc(sizeof(int)*(k+1));
    obj->front = obj->rear = 0;
    obj->k = k;
    return obj;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    return obj->front == obj->rear;
}
 
bool myCircularQueueIsFull(MyCircularQueue* obj) {
    return (obj->rear+1)%(obj->k+1)==obj->front;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if(myCircularQueueIsFull(obj))
    return false;
    obj->a[obj->rear++] = value;
    obj->rear%=(obj->k+1);
    return true;
}
 
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    return false;
    ++obj->front;
     obj->front%=(obj->k+1);
     return true;
}
 
int myCircularQueueFront(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    return -1;
 
    return obj->a[obj->front];
}
 
int myCircularQueueRear(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    return -1;
 
    if(obj->rear==0)
    {
        return obj->a[obj->k];
    }else
    {
        return obj->a[obj->rear-1];
    }
}
 
 
void myCircularQueueFree(MyCircularQueue* obj) {
    free(obj->a);
    free(obj);
}


以上便是本文所有内容了,如有错误请各位大佬不吝赐教,感谢留言

目录
相关文章
|
5月前
刷爆leetcode第一期
刷爆leetcode第一期
22 1
|
5月前
刷爆leetcode第六期
刷爆leetcode第六期
18 0
|
5月前
|
测试技术 C语言
刷爆leetcode第五期
刷爆leetcode第五期
21 0
|
5月前
刷爆leetcode第七期
刷爆leetcode第七期
18 0
|
5月前
|
索引
刷爆leetcode第四期
刷爆leetcode第四期
17 0
|
5月前
|
索引
刷爆leetcode第三期
刷爆leetcode第三期
23 0
|
5月前
刷爆leetcode第二期
刷爆leetcode第二期
26 0
|
算法 测试技术
刷爆 LeetCode 双周赛 100,单方面宣布第一题最难
上周末是 LeetCode 第 100 场双周赛,你参加了吗?这场周赛整体没有 Hard 题,但是也没有 Easy 题。第一题国服前百名里超过一半人 wa,很少见。
120 0