小工具知识网

当前位置: 首页 > 行业知识 > 驾驭栈和队列,首先逃不开这些(有效括号、栈和队列相互模拟、循环队列)

行业知识

驾驭栈和队列,首先逃不开这些(有效括号、栈和队列相互模拟、循环队列)

2026-11-05 07:08:43 来源:互联网转载

一.有效括号

. - 力���(LeetCode)

给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

示例 1:

输入:s = "()"输出:true

示例 2:

输入:s = "()[]{}"输出:true

示例 3:

输入:s = "(]"输出:false

提示:

  • 1 p    assert(st);/p p    st-data = NULL;/p p    st->top = 0;

        st->size = 0;

    }

    //销毁栈

    void destroyStack(Stack* st)

    {

        assert(st);

        free(st->data);

        st->data = NULL;

        st->size = st->top = 0;

    }

    //栈是否为空

    bool isEmpty(Stack* st)

    {

        assert(st);

        return st->top == 0;

    }

    //出栈

    void popStack(Stack* st)

    {

        assert(st);

        assert(!isEmpty(st));

        st->top--;

    }

    //入栈

    void pushStack(Stack* st, StackData data)

    {

        assert(st);

        if (st->top == st->size)

        {

            int newsize = st->size == 0 ? 4 : 2 * st->size;

            StackData* temp = (StackData*)realloc(st->data, sizeof(StackData) * newsize);

            if (temp != NULL)

            {

                st->data = temp;

                st->size = newsize;

            }

        }

        st->data[st->top] = data;

        st->top++;

    }

    //取出栈顶元素

    StackData topStack(Stack* st)

    {

        assert(st);

        assert(!isEmpty(st));

        return st->data[st->top - 1];

    }

    //栈的大小

    int sizeStack(Stack* st)

    {

        assert(st);

        return st->top;

    }

    bool isValid(char* s) {

        Stack st;

        initStack(&st);

        int lcount = 0, rcount = 0;

        for (int i = 0; s[i] != '\0'; i++)

        {

            if (s[i] == '(' || s[i] == '[' || s[i] == '{')

                {

                    pushStack(&st, s[i]);

                    lcount++;

                }

            else

            {

                rcount++;

                if (isEmpty(&st))

                {

                    destroyStack(&st);

                    return false;

                }

                char str = topStack(&st);

                if ((s[i] == ')' && str == '(') ||

                    (s[i] == ']' && str == '[') ||

                    (s[i] == '}' && str == '{'))

                {

                    popStack(&st);

                }

            }

        }

        return isEmpty(&st) && rcount == lcount;

    }

    二.用栈实现队列

    请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

    实现 MyQueue 类:

    • void push(int x) 将元素 x 推到队列的末尾
    • int pop() 从队列的开头移除并返回元素
    • int peek() 返回队列开头的元素
    • boolean empty() 如果队列为空,返回 true ;否则,返回 false

      说明:

      • 你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
      • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

        示例 1:

        输入:["MyQueue", "push", "push", "peek", "pop", "empty"][[], [1], [2], [], [], []]输出:[null, null, null, 1, 1, false]解释:MyQueue myQueue = new MyQueue();myQueue.push(1); // queue is: [1]myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)myQueue.peek(); // return 1myQueue.pop(); // return 1, queue is [2]myQueue.empty(); // return false

        提示:

        • 1 p    assert(st);/p p    st-data = NULL;/p p    st->top = 0;

              st->size = 0;

          }

          //销毁栈

          void destroyStack(Stack* st)

          {

              assert(st);

              free(st->data);

              st->data = NULL;

              st->size = st->top = 0;

          }

          //栈是否为空

          bool isEmpty(Stack* st)

          {

              assert(st);

              return st->top == 0;

          }

          //出栈

          void popStack(Stack* st)

          {

              assert(st);

              assert(!isEmpty(st));

              st->top--;

          }

          //入栈

          void pushStack(Stack* st, StackData data)

          {

              assert(st);

              if (st->top == st->size)

              {

                  int newsize = st->size == 0 ? 4 : 2 * st->size;

                  StackData* temp = (StackData*)realloc(st->data, sizeof(StackData) * newsize);

                  if (temp != NULL)

                  {

                      st->data = temp;

                      st->size = newsize;

                  }

              }

              st->data[st->top] = data;

              st->top++;

          }

          //取出栈顶元素

          StackData topStack(Stack* st)

          {

              assert(st);

              assert(!isEmpty(st));

              return st->data[st->top - 1];

          }

          //栈的大小

          int sizeStack(Stack* st)

          {

              assert(st);

              return st->top;

          }

           

          typedef struct {

            Stack st1;

            Stack st2;  

          } MyQueue;

           

          MyQueue* myQueueCreate() {

              MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));

              initStack(&obj->st1);

              initStack(&obj->st2);

              return obj;

          }

          void myQueuePush(MyQueue* obj, int x) {

              pushStack(&obj->st1, x);

          }

          int myQueuePop(MyQueue* obj) {

              int top = myQueuePeek(obj);

              popStack(&obj->st2);

              return top;

          }

          int myQueuePeek(MyQueue* obj) {

              if(isEmpty(&obj->st2))

              {

                  while(!isEmpty(&obj->st1))

                  {

                      int top = topStack(&obj->st1);

                      popStack(&obj->st1);

                      pushStack(&obj->st2, top);

                  }

              }

              return topStack(&obj->st2);

          }

          bool myQueueEmpty(MyQueue* obj) {

              return isEmpty(&obj->st1) && isEmpty(&obj->st2);

          }

          void myQueueFree(MyQueue* obj) {

              destroyStack(&obj->st1);

              destroyStack(&obj->st2);

              free(obj);

          }

          /**

           * Your MyQueue struct will be instantiated and called as such:

           * MyQueue* obj = myQueueCreate();

           * myQueuePush(obj, x);

           * int param_2 = myQueuePop(obj);

           * int param_3 = myQueuePeek(obj);

           * bool param_4 = myQueueEmpty(obj);

           * myQueueFree(obj);

          */

          三.用队列实现栈

          请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。

          实现 MyStack 类:

          • void push(int x) 将元素 x 压入栈顶。
          • int pop() 移除并返回栈顶元素。
          • int top() 返回栈顶元素。
          • boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

            注意:

            • 你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。
            • 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

              示例:

              输入:["MyStack", "push", "push", "top", "pop", "empty"][[], [1], [2], [], [], []]输出:[null, null, null, 2, 2, false]解释:MyStack myStack = new MyStack();myStack.push(1);myStack.push(2);myStack.top(); // 返回 2myStack.pop(); // 返回 2myStack.empty(); // 返回 False

              提示:

              • 1 p    assert(pq);/p p    pq-phead = pq->ptail = NULL;

                    pq->size = 0;

                }

                //队列的销毁

                void destroyQueue(Queue* pq)

                {

                    assert(pq);

                    QNode* cur = pq->phead;

                    while (cur)

                    {

                        QNode* next = cur->next;

                        free(cur);

                        cur = next;

                    }

                }

                //建立节点

                QNode* createQNode(QueueData data)

                {

                    QNode* pcur = (QNode*)malloc(sizeof(QNode));

                    if (pcur == NULL)

                        perror("malloc fail");

                    else

                    {

                        pcur->data = data;

                        pcur->next = NULL;

                    }

                    return pcur;

                }

                //插入元素

                void pushQueue(Queue* pq, QueueData data)

                {

                    assert(pq);

                    QNode* newNode = createQNode(data);

                    if (pq->phead == NULL)

                        pq->phead = pq->ptail = newNode;

                    else

                    {

                        pq->ptail->next = newNode;

                        pq->ptail = pq->ptail->next;

                    }

                    pq->size++;

                }

                //删除元素

                void popQueue(Queue* pq)

                {

                    assert(pq);

                    assert(pq->phead);

                    if (pq->phead->next == NULL)

                    {

                        free(pq->phead);

                        pq->phead = pq->ptail = NULL;

                    }

                    else

                    {

                        QNode* next = pq->phead->next;

                        free(pq->phead);

                        pq->phead = next;

                    }

                    pq->size--;

                }

                //取出队首元素

                QueueData topQueue(Queue* pq)

                {

                    assert(pq);

                    assert(pq->phead);

                    return pq->phead->data;

                }

                //取出队尾元素

                QueueData backQueue(Queue* pq)

                {

                    assert(pq);

                    assert(pq->phead);

                    return pq->ptail->data;

                }

                //计算队列长度

                int sizeQueue(Queue* pq)

                {

                    assert(pq);

                    return pq->size;

                }

                bool isEmpty(Queue* pq)

                {

                    assert(pq);

                    return !pq->phead;

                }

                void printQueue(Queue* pq)

                {

                    assert(pq);

                    QNode* cur = pq->phead;

                    while (cur)

                    {

                        printf("%d ", cur->data);

                        cur = cur->next;

                    }

                }

                typedef struct {

                    Queue q1;

                    Queue q2;

                } MyStack;

                 

                MyStack* myStackCreate() {

                    MyStack* obj = (MyStack*)malloc(sizeof(MyStack));

                    initQueue(&obj->q1);

                    initQueue(&obj->q2);

                    return obj;

                }

                void myStackPush(MyStack* obj, int x) {

                    if(!isEmpty(&obj->q1))

                    pushQueue(&obj->q1, x);

                    else return pushQueue(&obj->q2, x);

                }

                int myStackPop(MyStack* obj) {

                    Queue* emptyQ = &obj->q1;

                    Queue* noemptyQ = &obj->q2;

                    if(!isEmpty(&obj->q1))

                    {

                        emptyQ = &obj->q2;

                        noemptyQ = &obj->q1;

                    }

                    while(sizeQueue(noemptyQ) > 1)

                    {

                        int temp = topQueue(noemptyQ);

                        popQueue(noemptyQ);

                        pushQueue(emptyQ, temp);

                    }

                    int top = topQueue(noemptyQ);

                    popQueue(noemptyQ);

                    return top;

                }

                int myStackTop(MyStack* obj) {

                    if(!isEmpty(&obj->q1))

                    return backQueue(&obj->q1);

                    else return backQueue(&obj->q2);

                }

                bool myStackEmpty(MyStack* obj) {

                    return isEmpty(&obj->q1) && isEmpty(&obj->q2);

                }

                void myStackFree(MyStack* obj) {

                    destroyQueue(&obj->q1);

                    destroyQueue(&obj->q2);

                    free(obj);

                }

                /**

                 * Your MyStack struct will be instantiated and called as such:

                 * MyStack* obj = myStackCreate();

                 * myStackPush(obj, x);

                 * int param_2 = myStackPop(obj);

                 * int param_3 = myStackTop(obj);

                 * bool param_4 = myStackEmpty(obj);

                 * myStackFree(obj);

                */

                四.循环队列

                设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。

                循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。

                你的实现应该支持如下操作:

                • MyCircularQueue(k): 构造器,设置队列长度为 k 。
                • Front: 从队首获取元素。如果队列为空,返回 -1 。
                • Rear: 获取队尾元素。如果队列为空,返回 -1 。
                • enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
                • deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
                • isEmpty(): 检查循环队列是否为空。
                • isFull(): 检查循环队列是否已满。

                  示例:

                  MyCircularQueue circularQueue = new MyCircularQueue(3); // 设置长度为 3circularQueue.enQueue(1);  // 返回 truecircularQueue.enQueue(2);  // 返回 truecircularQueue.enQueue(3);  // 返回 truecircularQueue.enQueue(4);  // 返回 false,队列已满circularQueue.Rear();  // 返回 3circularQueue.isFull();  // 返回 truecircularQueue.deQueue();  // 返回 truecircularQueue.enQueue(4);  // 返回 truecircularQueue.Rear();  // 返回 4

                  提示:

                  • 所有的值都在 0 至 1000 的范围内;
                  • 操作数将在 1 至 1000 的范围内;
                  • 请不要使用内置的队列库。

                    typedef struct {

                        int* queue;

                        int head;

                        int rear;

                        int k;

                    } MyCircularQueue;

                     

                    MyCircularQueue* myCircularQueueCreate(int k) {

                        MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));

                        int* q = (int*)malloc(sizeof(int) * (k+1));

                        obj->queue = q;

                        obj->k = k;

                        obj->head = 0;

                        obj->rear = 0;

                        return obj;

                    }

                    bool myCircularQueueIsEmpty(MyCircularQueue* obj) {

                        return (obj->rear)%(obj->k+1) == (obj->head)%(obj->k+1);

                    }

                    bool myCircularQueueIsFull(MyCircularQueue* obj) {

                        return (obj->rear+1)%(obj->k+1)==(obj->head)%(obj->k+1);

                    }

                    bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {

                        if(myCircularQueueIsFull(obj))

                        return false;

                        else

                        {

                            obj->queue[obj->rear] = value;

                            obj->rear++;

                            (obj->rear) %= (obj->k+1);

                            return true;

                        }

                    }

                    bool myCircularQueueDeQueue(MyCircularQueue* obj) {

                        if(myCircularQueueIsEmpty(obj))

                        return false;

                        else

                        {

                            obj->head++;

                            (obj->head) %= (obj->k+1);

                            return true;

                        }

                    }

                    int myCircularQueueFront(MyCircularQueue* obj) {

                        if(myCircularQueueIsEmpty(obj))

                        return -1;

                        else return obj->queue[(obj->head) % (obj->k+1)];

                    }

                    int myCircularQueueRear(MyCircularQueue* obj) {

                        if(myCircularQueueIsEmpty(obj))

                        return -1;

                        else return obj->queue[(obj->rear+obj->k)%(obj->k+1)];

                    }

                    void myCircularQueueFree(MyCircularQueue* obj) {

                        free(obj->queue);

                        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);

                    */

上一篇:揭秘含税单价计算,税务知识轻松掌握!

下一篇:探究Spring Boot 中实现跨域的几种方式