算法day09 | Java | 栈和队列 | LeetCode 232,225,20,1047

70 阅读2分钟

java语法

《Java中的栈和队列操作,相互实现》

class MyQueue全局定义不能在函数里。

StringBuffer

StringBuffer res = new StringBuffer();

用下标访问
res.charAt(i)

用下标删除
res.deleteCharAt(i);

填充
res.append(c); // char c = s.charAt(i); (String s)

StringBuffer->String
res.toString();

232.用栈实现队列

书写错误1:错误原因是,类MyQueue里所有函数能访问的mystack需要定义在全局,不能定义在构造函数里。 image.png

书写错误2:这里有两个错误,①错把while写成if ②在数字全部处理完之后,也就是18行没有把新的元素添加进去。 image.png

修改了while以及添加新元素其实还是错的,在push这一步的话很容易写错。而且要倒来倒去的。

正确解法:

class MyQueue {
    Stack<Integer>instack;
    Stack<Integer>outstack;

    public MyQueue() {
        instack = new Stack<>();
        outstack = new Stack<>();
    }
    
    public void push(int x) {
        instack.push(x);
    }
    
    public int pop() {
       dumpstackIn();
       return outstack.pop();
    }
    
    public int peek() {
        dumpstackIn();
       return outstack.peek();
    }
    
    public boolean empty() {
        return instack.isEmpty()&&outstack.isEmpty();
    }

    private void dumpstackIn(){ 
        if(!outstack.isEmpty()) return;

        //outstack为空,把instack存储的元素倒去out
        while(!instack.isEmpty()) {
            int e = instack.pop();
            outstack.push(e);
        }
    }
}

225. 用队列实现栈

卡哥的思路,不用两个队列实现栈。

正确解法: 要非常注意public int top() 这个函数的实现。

class MyStack {
    Queue<Integer> queue;

    public MyStack() {
        queue = new LinkedList<>();
    }
    
    public void push(int x) {
        queue.offer(x);
    }
    
    public int pop() {
        rePosition();
        return queue.poll();
    }
    
    public int top() {
        rePosition();
        //这里虽然能得到队头,但不删除,所以还要把它放到队列最后面
        int res = queue.poll();
        queue.offer(res);
        return res;
    }
    
    public boolean empty() {
        return queue.isEmpty();
    }

    public void rePosition(){ 
        int size = queue.size();
        for(int i=1; i<size; i++) {
            int e = queue.poll();
            queue.offer(e);
        }
    }
}

20. 有效的括号

这题可以用双向队列解决。

三种场景不匹配:多了左括号,多了右括号,左右括号不匹配

错误1:从右往左遍历数组,而不是从左往右。

正确解法:

class Solution {
    public boolean isValid(String s) {
        Stack<Character>right = new Stack<>();
        // Stack<Character>left = new Stack<>();

        for(int i=s.length()-1; i>=0; i--) { //这里从右往左遍历
            char ch = s.charAt(i);
            if(ch=='}' || ch==']' || ch==')') {
                right.push(ch);
            } else {
                //左括号多了
                if(right.isEmpty()) return false;
                char rtop = right.peek();
                if(ch=='(' && rtop==')' 
                    || ch=='[' && rtop==']'
                    || ch=='{' && rtop=='}') {
                        right.pop();
                } else {
                    //左右括号不匹配
                    return false;
                }
            }
        }
        //右括号多了
        if(!right.isEmpty()) return false;

        return true;
    }
}

1047. 删除字符串中的所有相邻重复项

class Solution {
    public String removeDuplicates(String s) {
        StringBuffer res = new StringBuffer();
        int top = -1;
        for(int i=0; i<s.length(); i++) {
            char ch = s.charAt(i);
            if(top >=0 && res.charAt(top)==ch) { 
                res.deleteCharAt(top);
                top--;
            } else {
                res.append(ch);
                top++;
            }
        }
        return res.toString();
    }
}

这里的if条件很重要。 image.png