232.用栈实现队列
思路:这题的思路就是用两个栈来实现队列的输出,因为队列是先进先出原则,所以当有元素如队列时,把这些元素加入到输入栈stackIn中,如果要输出的时候,要先判断输出栈stackOut是否有元素,如果有元素直接输出,如果没有元素就把输入栈中的所有元素加入到输出栈之后再输出(这里为什么是所有元素呢,如果你不把statckIn中所有元素都压入stackOut中,后续输出会得不到队列的输出结果的,自己可以试着举例试试)
代码:
class MyQueue {
Stack<Integer> stackIn;
Stack<Integer> stackOut;
public MyQueue() {
stackIn = new Stack<>(); // 进栈
stackOut = new Stack<>(); // 出栈
}
public void push(int x) {
stackIn.push(x);
}
public int pop() {
dumpstackIn();
return stackOut.pop();
}
public int peek() {
dumpstackIn();
return stackOut.peek();
}
public boolean empty() {
return stackIn.isEmpty() && stackOut.isEmpty();
}
private void dumpstackIn(){
if(!stackOut.isEmpty()) return ;
while(!stackIn.isEmpty()){
stackOut.push(stackIn.pop());
}
}
}
225. 用队列实现栈
思路:这里运用一个队列实现栈。首先push即正常入栈queue.add();pop时,因为要删除的是栈顶元素,但是我们push把它放到了队列的末尾,所以我们要设置一个rePosistion方法,把出来这个栈顶元素外的其他元素提取出来重新加入到队列中,再queue.poll()即可得到栈顶元素;top时,就是把栈顶元素提取出来,但是不删除,所以我们执行rePosition方法后,把栈顶元素用result存储,再把result存入队列中,保证了原始入队列的顺序不变,后续只要执行rePosition还是可以得到该栈顶元素
代码:
class MyStack {
Queue<Integer> queue;
public MyStack() {
queue = new LinkedList<>();
}
public void push(int x) {
queue.add(x);
}
public int pop() {
rePosition();
return queue.poll();
}
public int top() {
rePosition();
//因为上面是把栈顶元素提到了队列最前面
int result=queue.poll();
//这里把队列的第一个元素提取出来后,再添加回队列中,就又保留了原来的入栈顺序,只要后面提取栈顶时再把元素提到队列最前面即可
queue.add(result);
return result;
}
public boolean empty() {
return queue.isEmpty();
}
//把除了栈顶元素外的其他元素提取出来重新加入加入队列中
public void rePosition(){
int size=queue.size();
size--;
while(size-->0){
queue.add(queue.poll());
}
}
}
20. 有效的括号
思路:设置一个栈,当遍历字符串时,如果遇到左括号,把对应的右括号放入栈中;当字符串还未遍历完,但是栈已经空了则返回false,如果遇到的是右括号,但是与栈中的栈顶的右括号不匹配,则返回false,如果与栈顶的右括号匹配,则删除栈顶元素,直到字符串遍历完。最后,如果当栈不为空,就表示此时的字符串的左括号多了,也是返回false,栈为空就返回true
代码:
class Solution {
public boolean isValid(String s) {
Deque<Character> deque = new LinkedList<>();
char ch;
for(int i=0;i<s.length();i++){
ch=s.charAt(i);
//遇到左括号,就把对应右括号放入栈中
if(ch=='('){
deque.push(')');
}else if(ch=='{'){
deque.push('}');
}else if(ch=='['){
deque.push(']');
}else if(deque.isEmpty() || deque.peek()!=ch){
//当字符串还未遍历完,但是栈已经为空,或者栈顶元素不等于当前遇到的右括号字符,则返回fasle
return false;
}else{
//表示此时栈顶的元素和当前遍历的右括号字符匹配,则去除栈顶元素
deque.pop();
}
}
//遍历到最后如果栈中还有元素,表示左括号多了,返回fasle即可
return deque.isEmpty();
}
}
1047. 删除字符串中的所有相邻重复项
思路:本题思路是用字符串代替栈的形式,获取最终字符串,省去转换字符串的转换。首先定义一个StringBuffer,设置一个默认长度top(用于后续比较);然后循环字符串s,判断当res中有元素,而且该元素与当前遍历到的字符相同时,则把当前res中的元素删除,res长度-1;若res用有元素且不与当前字符相同或者res没有元素时,就把当前的字符加入到res中,长度+1 。最后返回res的字符串形式即可
解释:这里为什么是res.charAt(top)和 res.deleteCharAt(top),因为我们把这个res的头作为栈尾,res的尾作为栈顶,所以删除的时候就是直接删除栈顶来操作,是为了后面防止倒叙输出字符串了
代码:
class Solution {
public String removeDuplicates(String s) {
//用字符串代表栈
StringBuffer res=new StringBuffer();
//代表res长度
int top=-1;
for(int i=0;i<s.length();i++){
char c=s.charAt(i);
//当res长度大于等于零即表示有元素时,而且res栈顶元素等于当前字符,则删除该栈顶元素
if(top>=0&&res.charAt(top)==c){
res.deleteCharAt(top);
top--;
}else{
//否则则添加该字符到栈中
res.append(c);//加入到res末尾
top++;//长度+1
}
}
//转换为字符串
return res.toString();
}
}