代码随想录算法训练营第9天 | 232.用栈实现队列 ,225. 用队列实现栈 ,20. 有效的括号 ,1047. 删除字符串中的所有相邻重复项
- 队列是先进先出,栈是先进后出
Deque类
first 和 Last 可以这样来理解
相对于出口来说 哪边是第一个 哪边就是first
用deque 实现stack
- push() -> addFirst()
- pop() -> pollFirst()
- peek() - > peekFirst()
deque 实现队列 queue
- add() -> addLast()
- poll() -> pollFirst()
- peek() -> peekFirst()
232.用栈实现队列
- 一个输入栈 一个输出栈
- 定义一个将输入栈元素倒进输出栈的方法 若输出栈不为空 则不能倒进去 因为顺序会乱 况且输出栈也可以pop()
class MyQueue {
Stack<Integer> stackIn = new Stack<>();
Stack<Integer> stackOut = new Stack<>();
public MyQueue() {
}
public void push(int x) {
stackIn.push(x);
}
public int pop() {
dumpStackIn();
return stackOut.pop();
}
public int peek() {
dumpStackIn();
int res = stackOut.pop();
stackOut.push(res);
return res;
}
public boolean empty() {
dumpStackIn();
if(stackOut.isEmpty()){
return true;
}else{
return false;
}
}
public void dumpStackIn(){
if(!stackOut.isEmpty()){
return;
}
while(!stackIn.isEmpty()){
stackOut.push(stackIn.pop());
}
}
}
/**
* 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. 用队列实现栈
- 用一个队列实现栈 pop操作可以将前面的所有元素弹出再重新添加到后面
- deque 为双端队列 可以在头尾操作
- Deque 接口继承了 Queue 接口 所以 Queue 中的 add、poll、peek等效于 Deque 中的 addLast、pollFirst、peekFirst
- 用deque的方法也可以直接实现
class MyStack {
Deque<Integer> que1 = new ArrayDeque<>();
//Deque<Integer> que2 = new ArrayDeque<>();
public MyStack() {
}
public void push(int x) {
que1.addLast(x);
}
public int pop() {
int size = que1.size();
size--;
while(size>0){
que1.addLast(que1.pollFirst());
size--;
}
return que1.pollFirst();
}
public int top() {
return que1.peekLast();
}
public boolean empty() {
return que1.isEmpty();
}
}
/**
* 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();
*/
20. 有效的括号
- 遇到匹配消除的问题可以用栈来解决
- 首先需要想清楚所有括号可能的出现情况
- 左边括号多
- 右边括号多
- 括号不匹配
往栈里面只存右括号
class Solution {
public boolean isValid(String s) {
Deque<Character> zhan = new ArrayDeque<>();
//Map<Character,Character> map = new HashMap<>();
for(int i =0; i<s.length();i++){
if(s.charAt(i)=='('){
zhan.addLast(')');
}else if(s.charAt(i)==('{')){
zhan.addLast('}');
}else if(s.charAt(i)==('[')){
zhan.addLast(']');
}else if(zhan.isEmpty() || s.charAt(i)!=zhan.peekLast() ){
return false;
}else{
zhan.pollLast();
}
}
return zhan.isEmpty();
}
}
用Map匹配左括号做判断
class Solution {
public boolean isValid(String s) {
Deque<Character> zhan = new ArrayDeque<>();
Map<Character,Character> map = new HashMap<>();
map.put('(',')');
map.put('{','}');
map.put('[',']');
for(Character ch:s.toCharArray()){
if(map.containsKey(ch)){
zhan.addLast(ch);
}else if(zhan.isEmpty() || ch!=map.get(zhan.pollLast())){ //不匹配或者左边括号多
return false;
}
}
//右边括号多
return zhan.isEmpty();
}
}
1047. 删除字符串中的所有相邻重复项
- 分清楚元素进出的顺序
- 遇到顺序匹配可以用栈
栈
class Solution {
public String removeDuplicates(String s) {
Deque<Character> zhan = new ArrayDeque<>();
for(int i=0;i<s.length();i++){
if(!zhan.isEmpty() && s.charAt(i)==zhan.peekFirst()){
zhan.pollFirst();
}else{
zhan.addFirst(s.charAt(i));
}
}
StringBuilder sb = new StringBuilder();
while(!zhan.isEmpty()){
sb.append(zhan.pollLast());
}
return sb.toString();
}
}
双指针
- fast 获取新元素 slow指向当前结果最后一位
class Solution {
public String removeDuplicates(String s) {
char[] ch = s.toCharArray();
int slow = 0;
int fast = 0;
while(fast<s.length()){
//用fast指针覆盖slow指针的值
ch[slow] = ch[fast];
//遇到前后相同值的 slow后退一步 下次循环用fast覆盖掉
if(slow>0 && ch[slow] == ch[slow-1]){
slow--;
}else{
slow++;
}
fast++;
}
return new String(ch,0,slow);
}
}