栈和队列相关的oj题

  1. 括号匹配问题

    其中题意是:给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。

    其中我是用栈的思想:“后进先出”的特征。将有关的左括号全部入栈,一个左括号必定遇到的是和自己匹配的右括号,否则不满足括号匹配问题;

    下面加入有一个字符串:s="{()}";将步骤用图来表示:

    栈和队列相关的oj题

    这个题不难,但是有两个点要注意一下,字符串只为左括号和只为右括号的情况,这两个情况考虑到,这个要用到栈,所以写这个代码要先把栈的相关操作实现一下,我直接把核心代码贴出来:

    栈和队列相关的oj题

2.用队列实现栈

  1. 题目的意思是:请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通队列的全部四种操作(入栈,出栈,获取栈顶元素,判空等);

首先这个题目要用到两个队列的先入先出规则,构成栈的后入先出的特性;栈和队列相关的oj题

核心代码:

//栈结构

typedef struct{

 Queue* q1;

   Queue* q2;

} MyStack;

/** Initialize your data structure here. */

MyStack* myStackCreate() {

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

    if(NULL==p)

    {

        assert(0);

        return NULL;

    }

    //初始化队列

     p->q1=(Queue*)malloc(sizeof(Queue));

     p->q2=(Queue*)malloc(sizeof(Queue));

    QueueInit(p->q1);

    QueueInit(p->q2);

    return p;

}

//q1入栈,站顶元素,q2:出栈

/** Push element x onto stack. */

void myStackPush(MyStack* obj, int x) {

    assert(obj);

    if(!QueueEmpty(obj->q1))

    {

     QueuePush(obj->q1, x);

    }

    else

    {

    QueuePush(obj->q2, x);

    }

}

bool myStackEmpty(MyStack* obj) {

   if(QueueEmpty(obj->q1)&&QueueEmpty(obj->q2))

         return true;

   return false;

}

/** Removes the element on top of the stack and returns that element. */

int myStackPop(MyStack* obj) {

     //出栈

     int top;

     assert(obj);

     if(QueueEmpty(obj->q1))

     {  //q1为空

    // for(int i=0;i<(QueueSize(&obj->q2)-1);i++)

    // {   

        while(QueueSize(obj->q2)>1)

        {

         //q2入队列

         QueuePush(obj->q1,QueueFront(obj->q2));

         //q1队头出队列

         QueuePop(obj->q2);

        }

    // }

     top=QueueFront(obj->q2);//获取队头元素

     QueuePop(obj->q2);

     }

     else

     { //q1不为空

         for(int i=(QueueSize(obj->q1)-1);i>0;i--)

    {   

       // while(QueueSize(&obj->q1)>1)

        //{

         //q2入队列

         QueuePush(obj->q2,QueueFront(obj->q1));

         //q1队头出队列

         QueuePop(obj->q1);

        //}

     }

     top=QueueFront(obj->q1);//获取队头元素

     QueuePop(obj->q1); 

     }

     return top;

}

/** Get the top element. */

int myStackTop(MyStack* obj) {

    //获取栈顶元素

    if(QueueEmpty(obj->q2))

    {

        //q2为空

       return QueueBack(obj->q1);

    }

    //q1为空

    return QueueBack(obj->q2);

}

/** Returns whether the stack is empty. */

//bool myStackEmpty(MyStack* obj) {

   //if(QueueEmpty(obj->q1)&&QueueEmpty(obj->q2))

        // return true;

   //return false;

//}

void myStackFree(MyStack* obj) {

    QueueDestroy(obj->q1);

    QueueDestroy(obj->q2);

    free(obj);

    obj=NULL;

}

3.栈实现队列

和上面的题类似,用两个栈实现队列的一些基本操作(入队,出队,获取元素,判空);栈和队列相关的oj题

基本思想是:入队的时候在入队的栈中入,出队的时候也让栈顶出,如果出队的栈为空,那直接将队尾的元素导入到出队的栈中,刚好栈底是最后导入的,它先出去,就这样用两个栈实现了队列的先入先出的特性;代码实现:

typedef struct {

  Stack* q1; //入队列

  Stack* q2;  //出队列

} MyQueue;

/** Initialize your data structure here. */

MyQueue* myQueueCreate() {

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

    if(NULL==p)

    {

        assert(0);

        return NULL;

    }

    StackInit(p->q1);

    StackInit(p->q2);

    return p;

}

/** Push element x to the back of queue. */

void myQueuePush(MyQueue* obj, int x) {

  //入队列,q1入队列

   StackPush(obj->q1, x);

}

/** Removes the element from in front of queue and returns that element. */

int myQueuePop(MyQueue* obj) {

   //出队列,q2出队列

   //判空

   int top=0;

   if(!StackEmpty(obj->q2))

   {

       top=StackTop(obj->q2);

      StackPop(obj->q2);

   }

   else

   {

       while(StackSize(obj->q1))

       {

           //将q1的元素全部移到q2中

           StackPush(obj->q2, StackTop(obj->q1));

           StackPop(obj->q1);

       }

       top=StackTop(obj->q2);

       StackPop(obj->q2);

   }

   return top;

}

/** Get the front element. */

int myQueuePeek(MyQueue* obj) {

    //队头元素

    if(StackEmpty(obj->q2))

    {

        while(StackSize(obj->q1))

       {

           //将q1的元素全部移到q2中

           StackPush(obj->q2, StackTop(obj->q1));

           StackPop(obj->q1);

       }

    }

    return StackTop(obj->q2);

    //return StackTop(&obj->q1);

}

/** Returns whether the queue is empty. */

bool myQueueEmpty(MyQueue* obj) {

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

}

void myQueueFree(MyQueue* obj) {

     StackDestroy(obj->q1);

     StackDestroy(obj->q2);

     free(obj);

}

4.循环队列

循环队列是为了解决正常队列随着不断地入队和出队的操作,出现了空间浪费的情况(假溢出);

循环队列使用数组实现,在实现循环队列的时候要注意几个点,插入的时候,队列是否满;出队的时候队列是否空;获取队尾元素的时候,指针的位置(头和尾部);

代码实现:

typedef struct {

   int* array;

   int front;

   int back;

   int capticpy;

   int count;

} MyCircularQueue;

MyCircularQueue* myCircularQueueCreate(int k) {

    MyCircularQueue s;

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

   p->array=(int*)malloc(sizeof(int)*k);

   if(NULL==p->array)

   {

      assert(0);

      return NULL;

   }

   p->front=p->back=p->count=0;

   p->capticpy=k;

   return p;

}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {

     return obj->count==0;

}

bool myCircularQueueIsFull(MyCircularQueue* obj) {

     return obj->count==obj->capticpy;

}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {

     //插入

     if(myCircularQueueIsFull(obj))

     {

         return false;

     }

     else

     {    //back在队尾的时候

         if(obj->back==obj->capticpy)

         {

             obj->back=0;

         }

         obj->array[obj->back]=value;

         obj->back++;

         obj->count++;

     }

     return true;

}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {

   //删除元素

   if(myCircularQueueIsEmpty(obj))

   {

       return false;

   }

   else

   {

       //obj->front++;

       obj->count--;

      if(obj->front==obj->capticpy)

        {

            obj->front=0;

        }

        else

        {

            obj->front++;

        }

   }

   return true;

}

int myCircularQueueFront(MyCircularQueue* obj) {

      assert(obj);

      if(myCircularQueueIsEmpty(obj))

      {

          return -1;

      }

      //队列不为空

      return obj->array[obj->front];

}

int myCircularQueueRear(MyCircularQueue* obj) {

      assert(obj);

      if(myCircularQueueIsEmpty(obj))

      {

          return -1;

      }

      //obj->back-1+obj->

      return obj->array[(obj->back-1+obj->capticpy)%obj->capticpy];

}

//bool myCircularQueueIsEmpty(MyCircularQueue* obj) {

     //return obj->count==0;

//}

//bool myCircularQueueIsFull(MyCircularQueue* obj) {

     //return obj->count==obj->capticpy;

//}

void myCircularQueueFree(MyCircularQueue* obj) {

    assert(obj);

    free(obj->array);

    obj->count=obj->capticpy=0;

    free(obj);

}


上一篇:oj-和最大的连续降序字符-java


下一篇:JavaWeb开发经验谈:业务行为相似DAO接口的统一封装与使用