刷爆leetcode第九期 0020

简介: 刷爆leetcode第九期 0020

题目编号0020


57701dbfaa23468d8809794d7efb1b15.png


题目分析


这里直接看图


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


这要怎么设计呢?


还是一样 我们先画图


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


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


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

794d480521b14fa6a56f6b88197a0294.png6356ed590c0a4f409bfc9ec17069d825.png


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


我们插入四个数据试试

fae28b9d3b9e4f84b07fe3b3f5589e94.png



咦 这个时候head和tail又相等了


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


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


好像没有特别好的方法


那么我们加一个空数据


这样子可不可以呢?


bcee6f07ffbf4c7fa8aad828071bb74c.png

这个时候呢?


我们好像可以使用公式


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


来判断是否为满


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


第一步 设计结构体

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


我们需要用到的数据有


数组 头指针 尾指针 数字K


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


第二步 初始化结构体


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


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


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


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


第三步 跳到第四步


fe3e811b15de4509b128f9ca92b13194.png


第四步 判断队列是否空或满


bool myCircularQueueIsEmpty(MyCircularQueue* obj) 
{
    //断言
    assert(obj);
    //如果说 头等于尾就为空 
    //否则就为假
    return head == tail;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) 
{
    //assert 
    assert(obj);
    //judge (tail +1) %(k+1)== head?
    return (tail+1)%(k+1) == head ;
}


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


第五步 插入数据


这里主要分两种情况讨论

00a0411fc51c47c2adde774a90a7f2d3.png


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


但是如果是这样子呢?

feb77a6f11d4485783ca13e60dbc6ab3.png


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


那么我们怎么来表示呢?


我们说


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


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


所以我们开始敲代码


bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
{
    // 断言
    assert(obj);
    //这个时候我们首先要判断整个队列是否为满 
    //所以我们先要判断队列是否为满
    //来都来了 顺便判断下是否为空
    if ((obj->tail+1)%(obj->k+1) == obj->front)
    {
        return false;
    }
    else
    {
        obj->arr[obj->tail] = value;
        //++obj->tail;
        obj->tail++;
        //obj->tail %= (obj->k+1);
        //++obj->tail;
        obj->tail %= (obj->k+1);
        return true;
    }
}


这样子就完成了


第六步 删除数据


这个的判断和前面一样


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


int myCircularQueueFront(MyCircularQueue* obj)
{
    if (obj->front == obj->tail)
    {
        return -1;
    }
    else
    {
        return obj->arr[obj->front];
    }
}


第七步 返回头数据


int myCircularQueueFront(MyCircularQueue* obj)
{
    if (obj->front == obj->tail)
    {
        return -1;
    }
    else
    {
        return obj->arr[obj->front];
    }
}


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


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


第八步 返回尾数据


这里要考虑一个特殊情况


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


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


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


int myCircularQueueRear(MyCircularQueue* obj)
{
    if (obj->front == obj->tail)
    {
        return -1;
    }
    else
    {
        if (obj->tail == 0)
        {
            return obj->arr[obj->k];
        }
        else
        {
            return obj->arr[obj->tail-1];
        }
    }    
}


总结


问题一


今天写代码遇到了两个问题

03e8f8ae8c8345ecb2fe03b55d718e30.png


一个是这个 我们开辟空间的时候 sizeof里面的内容填错了


上一次已经出现了一个没有填sizeof的问题 下次一定要注意

e57eef5268bf4ed394c90babd787c2d3.png


这里解决下就可以了


问题二


a9d4afbd0d76485cb295e650851edcec.png


这里还有一个报错就是我们没有在前面声明就开始使用函数了


leetcode不会提前声明函数的


所以我们刷题的时候要自己来声明


源码


// 使用数组模式来设计 
#include<stdbool.h>
typedef struct
{
    int* arr;
    int tail;
    int front;
    int k;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) 
{
    MyCircularQueue* cq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    cq->arr = (int *)malloc(sizeof(int)*(k+1));
    cq->tail = 0;
    cq->front = 0;
    cq->k = k;
    return cq;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
{
    // 断言
    assert(obj);
    //这个时候我们首先要判断整个队列是否为满 
    //所以我们先要判断队列是否为满
    //来都来了 顺便判断下是否为空
    if ((obj->tail+1)%(obj->k+1) == obj->front)
    {
        return false;
    }
    else
    {
        obj->arr[obj->tail] = value;
        //++obj->tail;
        obj->tail++;
        //obj->tail %= (obj->k+1);
        //++obj->tail;
        obj->tail %= (obj->k+1);
        return true;
    }
}
bool myCircularQueueDeQueue(MyCircularQueue* obj)
{
    assert(obj);
    // 这里相同 如果队列为空就返回false  如果不为空再讨论
    if(obj->front==obj->tail)
    {
        return false;
    }
    else
    {
        obj->front++;
        obj->front %= (obj->k+1);
        return true;
    }
}
int myCircularQueueFront(MyCircularQueue* obj)
{
    if (obj->front == obj->tail)
    {
        return -1;
    }
    else
    {
        return obj->arr[obj->front];
    }
}
int myCircularQueueRear(MyCircularQueue* obj)
{
    if (obj->front == obj->tail)
    {
        return -1;
    }
    else
    {
        if (obj->tail == 0)
        {
            return obj->arr[obj->k];
        }
        else
        {
            return obj->arr[obj->tail-1];
        }
    }    
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) 
{
    return obj->front == obj->tail;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) 
{
    return (obj->tail+1)%(obj->k+1) == obj->front;
}
void myCircularQueueFree(MyCircularQueue* obj) 
{
    free(obj->arr);
    obj->arr=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);
*/
相关文章
|
18天前
刷爆leetcode第一期
刷爆leetcode第一期
8 1
|
18天前
刷爆leetcode第八期
刷爆leetcode第八期
6 0
|
18天前
刷爆leetcode第六期
刷爆leetcode第六期
5 0
|
18天前
刷爆leetcode第七期
刷爆leetcode第七期
5 0
|
18天前
|
测试技术 C语言
刷爆leetcode第五期
刷爆leetcode第五期
12 0
|
18天前
|
索引
刷爆leetcode第四期
刷爆leetcode第四期
7 0
|
18天前
|
索引
刷爆leetcode第三期
刷爆leetcode第三期
8 0
|
18天前
刷爆leetcode第二期
刷爆leetcode第二期
11 0
|
测试技术 C语言
刷爆leetcode第六期 0017
刷爆leetcode第六期 0017
75 0
刷爆leetcode第六期 0017