力扣刷题记录(一)思路尽量好理解

目录

第20题:有效的括号

第225题:用队列实现栈

第232题:用栈实现队列

第155题:最小栈


第20题:有效的括号

 题目描述

                                               

 代码:

class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();
        //遍历整个字符串,最多只有三对括号
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            //只有这几种情况才可以入栈;
            // 不入栈就出栈,为空就说明这个字符串一个都没进去,不可能为真
            if (c == '(' || c == '[' || c == '{') {
                stack.push(c);
            } else {
                if (stack.isEmpty()) {
                    return false;
                }
                //出栈情况的具体情况
                char topChar = stack.pop();
                //比较当前括号和栈顶括号是否匹配,不匹配则错误
                if (c == ')' && topChar != '(') {
                    return false;
                }
                if (c == ']' && topChar != '[') {
                    return false;
                }
                if (c == '}' && topChar != '{') {
                    return false;
                }
            }
        }
        //如果一切顺利则全部进栈之后又出栈,栈必为空
        return stack.isEmpty();
    }
}

注意:java官方并不建议使用stack类,因为stack类是继承自vector,使用stack会继承vector的方法,同样,即使是官方建议使用的Deque接口,也一样不合适。但此处作为一个做题方式,可以使用。如在面试中遇到质疑此问题的面试官,需要进行解释,或自己实现一个stack类。


第225题:用队列实现栈

题目描述:

                                                 

思路:

题目要求最多使用两个队列实现,其实只用一个队列就可以实现。栈的操作是从栈顶进入,从栈顶出来,所以用队列实现栈时,栈顶应该是从队头插入,否则出栈无法实现。例如,进栈是1234,出栈是4321,而队列原本的出栈是1234。

代码:

class MyStack {

    private Queue<Integer> queue;

    /** Initialize your data structure here. */
    public MyStack() {
        queue = new LinkedList<>();
    }

    //用队列实现栈时,要从队列的头插入,实现方式就是队列先把原来的依次出,再依次进
    /** Push element x onto stack. */
    public void push(int x) {
        queue.add(x);
        //i自己理解下,这里非常重要
        for (int i = 1; i < queue.size(); i++) {
            queue.add(queue.remove());
        }
    }
    
    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
        return queue.remove();
    }
    
    /** Get the top element. */
    public int top() {
        return queue.peek();
    }
    
    /** Returns whether the stack is empty. */
    public boolean empty() {
        return queue.isEmpty();
    }
}

注意:个人觉得重点不只是对栈,队列的性质的考察,更是对队列方法的考察,建议随手阅读jdk-api文档


第232题:用栈实现队列

题目描述:

                                 

思路:

参考队列的原始思路,比较好理解的解法就是以栈1为基,两个栈来回折腾,最终在栈1上实现队列的操作

代码:

class MyQueue {

    private Stack<Integer> stack1;
    private Stack<Integer> stack2;

    /** Initialize your data structure here. */
    public MyQueue() {
        stack1 = new Stack<>();
        stack2 = new Stack<>();
    }
    
    /** Push element x to the back of queue. */
    public void push(int x) {
        stack1.push(x);
    }
    
    /** Removes the element from in front of queue and returns that element. */
    public int pop() {
        while(!stack1.empty()){
            stack2.push(stack1.pop());
        }
        int res = stack2.pop();
        while(!stack2.empty()){
            stack1.push(stack2.pop());
        }
        return res;
    }
    
    /** Get the front element. */
    public int peek() {
        while(!stack1.empty()){
            stack2.push(stack1.pop());
        }
        int res = stack2.peek();
        while(!stack2.empty()){
            stack1.push(stack2.pop());
        }
        return res;
    }
    
    /** Returns whether the queue is empty. */
    public boolean empty() {
        return stack1.empty();
    }
}

但考虑到还有”进阶“,因此可以直接使用两个栈,共同实现队列。

代码:

class MyQueue {

    private Stack<Integer> stack1;
    private Stack<Integer> stack2;
    //记录栈底
    int front;

    /**
     * Initialize your data structure here.
     */
    public MyQueue() {
        stack1 = new Stack<>();
        stack2 = new Stack<>();
    }

    /**
     * Push element x to the back of queue.
     */
    public void push(int x) {
        //如果栈1为空,则进入的栈1的第一个元素就是栈底,记录。
        if (stack1.empty()) {
            front = x;
        }
        //栈顶插入
        stack1.push(x);
    }

    /**
     * Removes the element from in front of queue and returns that element.
     */
    public int pop() {
        //队列要得到队首
        //栈2为空时,就把栈1依次出栈,在栈2中依次进栈,栈1为空时,栈底到栈2的栈顶。
        if(stack2.empty()){
            while(!stack1.empty()){
                stack2.push(stack1.pop());
            }
        }
        return stack2.pop();
    }

    /**
     * Get the front element.
     */
    public int peek() {
        if(stack2.empty()){
            return front;
        }
        return stack2.peek();
    }

    /**
     * Returns whether the queue is empty.
     */
    public boolean empty() {
        return stack1.empty() && stack2.empty();
    }
}

注意:这个实现在时间复杂度上是全O(1),但空间复杂度,pop为O(n),其他为O(1)


第155题:最小栈

 题目描述

                               

代码:

class MinStack {

    private Deque<Integer> dataStack;
    private Deque<Integer> minStack;

    /**
     * initialize your data structure here.
     */
    public MinStack() {
        dataStack = new LinkedList<>();
        minStack = new LinkedList<>();
    }

    //这里是关键,确保每次minStack都会同步添加元素,else里一定要用peek
    public void push(int x) {
        dataStack.push(x);
        if (minStack.isEmpty() || x <= minStack.peek()) {
            minStack.push(x);
        } else {
            minStack.push(minStack.peek());
        }
    }

    public void pop() {
        dataStack.pop();
        minStack.pop();
    }

    public int top() {
        return dataStack.peek();
    }

    public int getMin() {
        return minStack.peek();
    }
}

注意:此题的重点在于理解题意,所谓最小栈,只是求栈中最小值的时间复杂度不为O(n),为O(1),前文中提到正常的栈官方并不建议使用,因此此处采用了官方建议的Deque接口,getMin之外的方法本来就是O(1),因此直接用,注意实现方式。当然此题最好的做法是用自己实现栈的方式来做。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TmxXd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值