232.用栈实现队列

思路:

用两个栈实现队列操作;定义两个栈,一个栈用于出栈outStack,另一个栈用于入栈inStack;当outStack为空时,则将inStack中的元素依次出栈并且加入到outStack中;

代码:

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() {
        inToOutParam();
        return outStack.pop();
    }
    
    public int peek() {
        inToOutParam();
       return outStack.peek();
    }
    
    public boolean empty() {
        return inStack.isEmpty() && outStack.isEmpty();
    }

    //将inStack中的元素加入到outStack中
    public void inToOutParam() {
        if (outStack.isEmpty()) {
            while (!inStack.isEmpty()) {
                Integer param = inStack.pop();
                outStack.push(param);
            }
        }
    }
}

225.用队列实现栈

思路:

用一个队列实现栈的话,入栈可以正常从队列的入口进入,出栈的时候将队列pop进行size-1次,然后依次重新push到队列,最后再进行一次pop将移除元素返回即可;

代码:

class MyStack {

    Deque<Integer> deque;

    public MyStack() {
        deque = new ArrayDeque<>();
    }
    
    public void push(int x) {
        deque.addFirst(x);
    }
    
    public int pop() {
        //此时,用一个队列实现栈的元素应该在队尾,我们将队列前边的所有元素都重新加入队列
        int num = deque.size() - 1;
        while (num > 0) {
            Integer last = deque.removeLast();
            deque.addFirst(last);
            num--;
        }
        return deque.removeLast();
    }
    
    public int top() {
        return deque.getFirst();
    }
    
    public boolean empty() {
        return deque.isEmpty();
    }
}

20.有效的括号

思路:

自己的思路是,创建两个栈,一个栈按照字符串的顺序放入一个栈strStack中,另一个栈tempStack用来临时存放左括号;

1、先将字符串字符从字符串尾至头依次压入strStack栈;

2、依次对strStack出栈,如果是左括号,则直接放入temp栈中,如果是右括号,则判断tempStack栈中的左括号和当前的右括号是否匹配,如果匹配则将tempStack也出栈,如果不匹配直接返回false;

3、最后判断两个栈是否都是空,如果都是空则校验通过;

代码:

class Solution {
    public boolean isValid(String s) {
        Stack<Character> tempStack = new Stack<>();
        Stack<Character> strStack = new Stack<>();
        for (int i = s.length()-1; i >=0; i--) {
            strStack.push(s.charAt(i));
        }
        while (!strStack.isEmpty()) {
            Character pop = strStack.pop();
            if (isLeft(pop)) { //如果是左括号就加入到temp栈中;
                tempStack.push(pop);
                continue;
            }
            if (isRight(pop)) {
                if (tempStack.isEmpty()) {
                    return false;
                }
                //对temp进行出栈,如果temp出栈和pop对应上,则双双跳出,如果没对应上,直接返回false;
                if (isMatch(tempStack.peek(), pop)) {
                    tempStack.pop();
                } else {
                    return false;
                }
            }
        }
        return tempStack.isEmpty() && strStack.isEmpty();
    }

    public boolean isLeft(Character s) {
        return '(' == s || '[' == s || '{' == s;
    }

    public boolean isRight(Character s) {
        return ')' == s || ']' == s || '}' == s;
    }

    public boolean isMatch(Character left, Character right) {
        if ('(' == left && ')' == right) {
            return true;
        }
        if ('[' == left && ']' == right) {
            return true;
        }
        if ('{' == left && '}' == right) {
            return true;
        }
        return false;
    }
}

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

思路:

1、定义一个栈,用来存放相邻不重复的字符;

2、对字符串s进行遍历,每次遍历到的字符c对栈顶元素进行比较,如果相同则栈顶进行pop,如果不相同则将字符c压入栈;

3、最后将栈中的元素按照栈底到栈顶的顺序输出成字符串返回即可;

代码:

class Solution {
    public String removeDuplicates(String s) {
        //定义一个栈从来存放未重复的字母元素
        Deque<Character> deque = new ArrayDeque();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (deque.isEmpty() || deque.getFirst() != c) {
                deque.addFirst(c);
            } else {
                deque.removeFirst();
            }
        }
        StringBuilder sb = new StringBuilder();
        while (!deque.isEmpty()) {
            sb.append(deque.removeLast());
        }
        return sb.toString();
    }
}

150.逆波兰表达式

思路:

1、先创建一个用于存放操作数的栈numStack;

2、遍历整个数组,如果不为操作数则push进操作数栈numStack中,如果为操作符的话,则从操作数栈中弹出两个操作数进行运算,并且将运算结果重新push进numStack中;

3、最后的计算结果就是numStack的最后一个元素,即栈顶元素;

代码:

class Solution {
    public int evalRPN(String[] tokens) {
        //用于存放操作数的栈
        Stack<Integer> numStack = new Stack<>();
        for (int i = 0; i < tokens.length; i++) {
            String token = tokens[i];
            if (isCompute(token)) {
                Integer num1 = numStack.pop();
                Integer num2 = numStack.pop();
                if ("+".equals(token)) {
                    numStack.push(num1+num2);
                }
                if ("-".equals(token)) {
                    numStack.push(num2-num1);
                }
                if ("*".equals(token)) {
                    numStack.push(num2*num1);
                }
                if ("/".equals(token)) {
                    numStack.push(num2/num1);
                }
            } else {
                numStack.push(Integer.valueOf(token));
            }
        }
        return numStack.pop();
    }

    public boolean isCompute(String s) {
        return "+".equals(s) || "-".equals(s) || "*".equals(s) || "/".equals(s);
    }
}
04-01 07:59