怎样应对IT面试与笔试-(三)

1.1.4 栈stack与队列queue

栈stack

部分定义参考自百度百科栈

  • 栈(stack)在计算机科学中是限定仅在表尾进行插入或删除操作的线性表,,是一种后进先出(LIFO )的数据结构。
  • 栈是一种数据结构,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据。
  • 栈是只能在某一端插入和删除的特殊线性表。
  • 栈的底层实现是基于数组或者链表
  • c++ stl中stack是一个容器适配器,stack默认的基础容器为deque容器(一种双端都可以进行删除插入操作的数据结构)

下面的例子说明图片来自维基百科:


怎样应对IT面试与笔试-(三)_第1张图片
Lifo_stack.png
queue队列

部分定义参考自百度百科队列

  • 队列是一种特殊的线性表,是一种先进先出(FIFO)的数据结构。
  • 队列只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。
  • 队列的底层实现也是基于数组或者链表。
  • c++ stl中queue是一个容器适配器,vector、list和deque都能够作为queue的基础容器,而与stack一样queue默认的基础容器也为deque容器
怎样应对IT面试与笔试-(三)_第2张图片
queue.png

232. Implement Queue using Stacks

使用stack模拟实现queue的功能,包括push、pop、peek、empty

1.举例子-画图-解题思路

实现queue的push,意味着每次的元素都要放在stack的底部,为了完成这样的效果,我们首先需要把stack1中的元素挨个取出放到辅助栈stack2中,然后把新来的元素直接放到stack1中,最后把stack2中的元素取出来再放到stack1中。

push示意图:


怎样应对IT面试与笔试-(三)_第3张图片
stack-queue.png

pop示意图:


怎样应对IT面试与笔试-(三)_第4张图片

queue的pop即stack1的top+pop操作(c++的stack,top只返回最顶元素,不会出栈,pop才会执行出栈操作)

2. 写核心逻辑代码
class MyQueue {
public:
    /** Initialize your data structure here. */
    MyQueue() {
        
    }
    
    /** Push element x to the back of queue. */
    void push(int x) {
        stack stack2;
        // 将stack1中的元素移动到stack2中
        while(!stack1.empty())
        {
            stack2.push(stack1.top());
            stack1.pop();
        }
        //将新push的元素放入stack1中
        stack1.push(x);
        //将stack2中的元素放回stack1中
        while(!stack2.empty())
        {
            stack1.push(stack2.top());
            stack2.pop();
        }
    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        //top方法只返回栈的顶值,不会出栈
        int value = stack1.top();
        //出栈操作是pop,但没有返回值
        stack1.pop();
        return value;
    }
    
    /** Get the front element. */
    int peek() {
        return stack1.top();
    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
        return stack1.empty();
    }
private:
    stack stack1;
};
3. 边界条件-无
4. 优化

每次push元素都要把元素经历stack1-stack2-stack1这样的流程是有些浪费的。可以考虑一种lazy的方式,同样准备数据结构与算法两个stack,pushi时候新元素直接放到stack1,pop或者peek时候,先看stack2中是否有元素,有直接出栈,没有则把stack1中的元素移动到stack2中。

怎样应对IT面试与笔试-(三)_第5张图片
class MyQueue {
public:
    /** Initialize your data structure here. */
    MyQueue() {
        
    }
    
    /** Push element x to the back of queue. */
    void push(int x) {
        stack1.push(x);
    }
    
    void shiftStack()
    {
        if(stack2.empty())
        {
            while(!stack1.empty())
            {
                stack2.push(stack1.top());
                stack1.pop();
            }
        }
    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        shiftStack();
        if(!stack2.empty())
        {
            int value = stack2.top();
            stack2.pop();
            return value;
        }
        return 0;
    }
    
    /** Get the front element. */
    int peek() {
        shiftStack();
        if(!stack2.empty())
        {
            return stack2.top();
        }
        return 0;
    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
        return stack1.empty() && stack2.empty();
    }

private:
    stack stack1,stack2;
};

5. 小结

stack 经常作为一种辅助手段实现更为复杂的一些算法(图的深度优先遍历),我们后面也会看到。常用的语言c++/java中都内置了stack的数据类型,请小伙伴们尝试理解和使用stack。框架图将在225题目的小结中一并给出。

225. Implement Stack using Queues

使用队列queue模拟实现stack的push、pop、top、empty函数

1.举例子-画图-解题思路

先考虑利用queue实现stack的push函数。我们要想办法每次把push的数据放到q1(queue)的头部,这时需要借助另外一个q2(queue),push到q1前先把q1中的数据依次取出放到q2中,然后将新数据push到q1中,最后把q2中数据依次取出再放回q1中。

怎样应对IT面试与笔试-(三)_第6张图片
217-op (7).png
2. 写核心逻辑代码
class MyStack {
public:
    /** Initialize your data structure here. */
    MyStack() {
        
    }
    
    /** Push element x onto stack. */
    void push(int x) {
        queue q2;
        //step1 step2 将queue1中元素放到queue2中
        while(!q1.empty())
        {
            q2.push(q1.front());
            q1.pop();
        }
        // step2 将新元素放到queue1中
        q1.push(x);
         //step3 setp4 再将queue2中元素放回queue1中
        while(!q2.empty())
        {
            q1.push(q2.front());
            q2.pop();
        }
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        int value = q1.front();
        q1.pop();
        return value;
    }
    
    /** Get the top element. */
    int top() {
        return q1.front();
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
        return q1.empty();
    }
private:
    queue q1;

};

3. 边界条件

题目已经帮我们限制了各种边界条件,不用在代码中说明

4. 优化

还有一种解法是只用一个queue来完成stack的push函数。具体思路是:将新元素push到queue1中,然后将新元素之前的各个元素依次取出来放到新元素后面,这样新元素最后就位于queue1的头部了。

怎样应对IT面试与笔试-(三)_第7张图片
//我们只重写这个push函数,其他函数的实现与未优化前的版本一致
/** Push element x onto stack. */
void push(int x) {
    int length = q1.size();
    q1.push(x);
    while(length--)
    {
        q1.push(q1.front());
        q1.pop();
    }
}
5. 小结

queue也经常作为一种辅助手段实现更为复杂的一些算法(图的广度优先遍历),我们后面也会遇到相应的例子。常用的语言c++/java中也都内置了queue的数据类型。

怎样应对IT面试与笔试-(三)_第8张图片

怎样应对IT面试与笔试-(一)
怎样应对IT面试与笔试-(二)
怎样应对IT面试与笔试-(三)
怎样应对IT面试与笔试-(四)
怎样应对IT面试与笔试-(五)
怎样应对IT面试与笔试-(五-1)
怎样应对IT面试与笔试-(六)
怎样应对IT面试与笔试-(七)
怎样应对IT面试与笔试-(八)
怎样应对IT面试与笔试-(九)
怎样应对IT面试与笔试-(十)
怎样应对IT面试与笔试-(十一)
怎样应对IT面试与笔试-(十二)
怎样应对IT面试与笔试-(十三)
怎样应对IT面试与笔试-(十四)
怎样应对IT面试与笔试-(十五)
怎样应对IT面试与笔试-(十六)

你可能感兴趣的:(怎样应对IT面试与笔试-(三))