232.用栈实现队列leetcode地址
class MyQueue {
private Stack<Integer> A;
private Stack<Integer> B;
public MyQueue() {
A = new Stack<>();
B = new Stack<>();
}
public void push(int x) {
A.push(x);
}
public int pop() {
if(!B.isEmpty()) return B.pop();
while(!A.isEmpty()){
B.push(A.pop());
}
return B.pop();
}
public int peek() {
if(!B.isEmpty()) return B.peek();
while(!A.isEmpty()){
B.push(A.pop());
}
return B.peek();
}
public boolean empty() {
return A.isEmpty() && B.isEmpty();
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/
双栈模拟队列,一个用于入栈,一个用于倒序
225. 用队列实现栈 leetcode地址
class MyStack {
Queue<Integer>q;
public MyStack() {
q = new LinkedList<>();
}
public void push(int x) {
q.add(x);
}
public int pop() {
rePosition();
return q.poll();
}
public int top() {
rePosition();
int result = q.poll();
q.add(result);
return result;
}
public boolean empty() {
return q.isEmpty();
}
public void rePosition(){
int size = q.size();
size--;
while(size-- != 0){
q.add(q.poll());
}
}
}
/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* boolean param_4 = obj.empty();
*/
单队列实现,将size-1个头依次移动到尾,实现栈的逻辑,JAVA中提供了双端队列Deque,直接实现就好了,但是没有练习意义。
- Queue:
- 仅支持从一端插入(入队)和从另一端移除(出队)。遵循先进先出(FIFO,First-In-First-Out)原则。
- Deque:
- 支持从两端插入和移除元素,可以看作是双向的队列。允许先进先出(FIFO)和后进先出(LIFO,Last-In-First-Out)操作。
- Queue:
- 常用方法包括:
add(E e)
: 将元素添加到队列尾部。remove()
: 移除并返回队列头部元素。peek()
: 返回队列头部元素,不移除它。
- 常用方法包括:
- Deque:
- 支持所有
Queue
方法,并额外提供以下方法:addFirst(E e)
: 将元素添加到队列头部。addLast(E e)
: 将元素添加到队列尾部。removeFirst()
: 移除并返回队列头部元素。removeLast()
: 移除并返回队列尾部元素。peekFirst()
: 返回队列头部元素,不移除它。peekLast()
: 返回队列尾部元素,不移除它。
- 支持所有
Queue<Integer> q = new LinkedList<>();
Deque<Integer> q = new ArrayDeque<>();
20. 有效的括号 leetcode地址
class Solution {
public boolean isValid(String s) {
Stack<Character> stc = new Stack<>();
for (int i = 0; i < s.length(); i++) {
char current = s.charAt(i);
// 判断开括号并压入栈
if (current == '(' || current == '{' || current == '[') {
stc.push(current);
} else {
// 如果栈为空或当前字符是闭括号,但栈顶不是对应的开括号,返回 false
if (stc.isEmpty()) return false;
char top = stc.pop();
if (!isMatchingPair(top, current)) {
return false;
}
}
}
// 如果栈为空,说明所有括号都匹配
return stc.isEmpty();
}
// 判断开闭括号是否匹配
private boolean isMatchingPair(char open, char close) {
return (open == '(' && close == ')') ||
(open == '{' && close == '}') ||
(open == '[' && close == ']');
}
// int size = s.length();
// if(size%2 != 0) return false;
// for(int i = 0; i < size; i++){
// if(i <size / 2 ){
// stc.push(s.charAt(i));
// }else{
// char temp = stc.pop();
// if(temp != s.charAt(i)){
// return false;
// }
// }
// }
// return true;
}
想法一想就会,代码一些漏洞百出,第一次写的代码,按中间位置之前的入栈之后的出栈比较,想成对称的了,忽略了以下这种情况。
输入:s = "()[]{}"
输出:true
1047. 删除字符串中的所有相邻重复项 leetcode地址
class Solution {
public String removeDuplicates(String s) {
ArrayDeque<Character> stack = new ArrayDeque<>();
for(char c : s.toCharArray()){
if(!stack.isEmpty() && c == stack.peek()){
stack.pop();
}else{
stack.push(c);
}
}
String str = "";
while(!stack.isEmpty()){
str = stack.pop() + str;
}
return str;
}
}
这道题用栈很巧妙用,动图很好理解原理
看来卡哥的思路发现String就可以做栈,但是代码没有栈的好懂。
class Solution {
public String removeDuplicates(String s) {
// 将 res 当做栈
// 也可以用 StringBuilder 来修改字符串,速度更快
// StringBuilder res = new StringBuilder();
StringBuffer res = new StringBuffer();
// top为 res 的长度
int top = -1;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
// 当 top > 0,即栈中有字符时,当前字符如果和栈中字符相等,弹出栈顶字符,同时 top--
if (top >= 0 && res.charAt(top) == c) {
res.deleteCharAt(top);
top--;
// 否则,将该字符 入栈,同时top++
} else {
res.append(c);
top++;
}
}
return res.toString();
}
}