代码随想录

`

代码随想录第十一天 | LeetCode 232.用栈实现队列 225.用队列实现栈


前言

用数组模拟栈:

// tt表示栈顶
int stk[N], tt = 0;

// 向栈顶插入一个数
stk[ ++ tt] = x;

// 从栈顶弹出一个数
tt -- ;

// 栈顶的值
stk[tt];

// 判断栈是否为空,如果 tt > 0,则表示不为空
if (tt > 0)
{

}

数组模拟队列

// hh 表示队头,tt表示队尾(插入和删除都是++操作)
int q[N], hh = 0, tt = -1;

// 向队尾插入一个数
q[ ++ tt] = x;

// 从队头弹出一个数
hh ++ ;

// 队头的值
q[hh];

// 判断队列是否为空,如果 hh <= tt,则表示不为空
if (hh <= tt)
{

}

一、LeetCode 232.用栈实现队列

题目解析:用栈来实现队列,因为栈是只有一个开口,但是队列却又两个开口。又因为顺序的问题,1.2.3.的进,就应该1.2.3.的出来.因此我们需要用到另一个栈。进两边栈,相当于顺序就不变了。哇塞,又是那个经典逻辑的逻辑,反转两次然后顺序正常。这里的顺序就是指的是第一次进栈,出来的会是反的顺序,那进两次栈就刚好可以调整顺序。
代码实现:定义一个入栈,一个出栈。stackin,stackout。入栈push(x)。放进出栈:判断入栈是否为空,然后while循环用出栈把入栈中的所有元素吸收。最后在进行出栈的弹出元素就好了。

C++代码ruxia

class MyQueue {
public:
	//用到两个栈
    stack<int> stIn;//入栈
    stack<int> stOut;//出栈
    MyQueue() {

    }
	//入栈弹入元素
    void push(int x) {
        stIn.push(x);
    }

    //放进出栈元素并且返回头部
    int pop() {
        // 先判断是不是有数据 ,不要直接往里放。   
        if (stOut.empty()) {
            // 只有当stOut为空的时候,再从stIn里导入数据(导入stIn全部数据)
            //这里其实还可以更加深入的去思考一下,就是为什么一定要stOut栈为空的时候我们才可以添加
        	//因为栈是先进先出,转换出的队列也要先进先出,但是你一旦把stIn栈的元素放到stOut栈中,新放入的元素就会更快的出来,就改变了顺序。
            while(!stIn.empty()) {
                stOut.push(stIn.top());//这就是stIn导入到stOut数据中
                stIn.pop();//导入一个弹出去一个。其次也是说判断条件一定要移动,不然会无限循环。
            }
        }
        int result = stOut.top();//将头部(接口)赋给result
        stOut.pop();
        return result;
    }
	//只需要返回头部就好了,不需要弹出,那么我们就先用pop取出并且弹出,之后在放进去(push)就好了
    int peek() {
        int res = this->pop(); // 直接使用已有的pop函数
        stOut.push(res); // 因为pop函数弹出了元素res,所以再添加回去
        return res;
    }

    
    bool empty() {
        return stIn.empty() && stOut.empty();//都没有了就是仓库没有了才说明队列没有元素
    }
};

JAVA代码如下

class MyQueue {
	//用到两个栈
    private Stack<Integer> in;// 输入栈
    private Stack<Integer> out;// 输出栈
    
    public MyQueue() {
        in = new Stack<>();
        out = new Stack<>();
    }
    
    public void push(int x) {
    	//入栈弹入元素
        in.push(x);
    }
    
    public int pop() {
         // 先判断是不是有数据 ,不要直接往里放。
        if(out.isEmpty()){
        	// 只有当out栈为空的时候,再从in栈里导入数据(导入in栈的全部数据)
        	//这里其实还可以更加深入的去思考一下,就是为什么一定要out栈为空的时候我们才可以添加
        	//因为栈是先进先出,转换出的队列也要先进先出,但是你一旦把in栈的元素放到out栈中,新放入的元素就会更快的出来,就改变了顺序。
            while(!in.isEmpty()){//这就是in栈导入到out栈数据中
                out.push(in.pop());
            }
        }
        return out.pop();
    }
    
    public int peek() {//其实本方法可以不那么麻烦的列出来完整的代码,可以直接运用pop方法,就像上面C++代码一样
        if(out.isEmpty()){
            while(!in.isEmpty()){
                out.push(in.pop());
            }
        }
        return out.peek();
    }
    
    public boolean empty() {
        return in.isEmpty() && out.isEmpty();
    }
}

二、 LeetCode:225. 用队列实现栈

题目解析:其实也可以向上一道题目一样使用两次队列来模拟栈也可以,但是这里有更好的方法,只用一个队列就好。我们只需要先把元素取出来,然后再重新加入队列里,直到即将弹出最后一个元素,那么第二次这个操作就是即将弹出倒数第二个元素,以此类推,说起来复杂,其实就是这个操作每次都进行(suze - 1 )次就好了。

C++代码如下(用两个队列的方法)

class MyStack {
public:
    queue<int> que1;
    queue<int> que2; // 辅助队列,用来备份
    /** Initialize your data structure here. */
    MyStack() {

    }

    /** Push element x onto stack. */
    void push(int x) {
        que1.push(x);
    }

    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        int size = que1.size();
        size--;
        while (size--) { // 将que1 导入que2,但要留下最后一个元素
            que2.push(que1.front());
            que1.pop();
        }

        int result = que1.front(); // 留下的最后一个元素就是要返回的值
        que1.pop();
        que1 = que2;            // 再将que2赋值给que1
        while (!que2.empty()) { // 清空que2
            que2.pop();
        }
        return result;
    }

    /** Get the top element. */
    int top() {
        return que1.back();
    }

    /** Returns whether the stack is empty. */
    bool empty() {
        return que1.empty();
    }
};

C++代码如下(一个队列的方法)

class MyStack {
public:
    queue<int> que;
    /** Initialize your data structure here. */
    MyStack() {

    }
    //加入元素
    void push(int x) {
        que.push(x);
    }
   //弹出头部元素并且记录元素。
    int pop() {
        int size = que.size();
        size--;//最大下标应该减一。
        while (size--) { // 将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部
            que.push(que.front());//弹出后重新放回来。A.push(B..front)把B的元素弹到A里面
            que.pop();
        }
        int result = que.front(); // 此时弹出的元素顺序就是栈的顺序了
        que.pop();
        return result;
    }

    //只需要获取头部元素
    int top() {
        return que.back();
    }

    //判断栈是否为空,一个1队列为空就好。
    bool empty() {
        return que.empty();
    }
};

JAVA代码如下(一个队列实现)

class MyStack {
    // Deque 接口继承了 Queue 接口
    // 所以 Queue 中的 add、poll、peek等效于 Deque 中的 addLast、pollFirst、peekFirst
    Deque<Integer> que1;
    /** Initialize your data structure here. */
    public MyStack() {
        que1 = new ArrayDeque<>();
    }
    
    //push方法
    public void push(int x) {
        que1.addLast(x);
    }
    
   //弹出并且获取头部元素
    public int pop() {
        int size = que1.size();
        size--;//只需要进行size-1次操作
        // 将 que1 导入 que2 ,但留下最后一个值
        while (size-- > 0) {
            que1.addLast(que1.peekFirst());
            que1.pollFirst();
        }

        int res = que1.pollFirst();
        return res;//返回值
    }
    
    //只需要获得,我们直接用函数就好
    public int top() {
        return que1.peekLast();
    }
    
    //是否为空,只需要队列为空。
    public boolean empty() {
        return que1.isEmpty();
    }
}

JAVA代码如下(两个队列):

class MyStack {
    // Deque 接口继承了 Queue 接口
    // 所以 Queue 中的 add、poll、peek等效于 Deque 中的 addLast、pollFirst、peekFirst
    Deque<Integer> que1; // 和栈中保持一样元素的队列
    Deque<Integer> que2; // 辅助队列
    /** Initialize your data structure here. */
    public MyStack() {
        que1 = new ArrayDeque<>();
        que2 = new ArrayDeque<>();
    }
    
    //仅仅添加
    public void push(int x) {
        que1.addLast(x);
    }
    
    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
        int size = que1.size();
        size--;
        // 将 que1 导入 que2 ,但留下最后一个值,注意智力也是要留下最后一个值
        while (size-- > 0) {
            que2.addLast(que1.peekFirst());
            que1.pollFirst();
        }

        int res = que1.pollFirst();//弹出来第一个
        // 将 que2 对象的引用赋给了 que1 ,此时 que1,que2 指向同一个队列
        que1 = que2;
        // 如果直接操作 que2,que1 也会受到影响,所以为 que2 分配一个新的空间
        que2 = new ArrayDeque<>();
        return res;
    }
    
    //获取头部。
    public int top() {
        return que1.peekLast();
    }
    
    /** Returns whether the stack is empty. */
    public boolean empty() {
        return que1.isEmpty();
    }
}

总结

今天的内容其实还是蛮简单的。好好理解结构,后面的底层没有钻研,要自己钻研一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值