232.用栈实现队列
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
解题思路:
由于栈是先进后出,队列是先进先出。因此定义两个栈,所有元素进入第一个栈In后,再全部进入第二个栈Out,这样便可实现先进入的元素也可以先出。
自定义一个方法dumpStackIn——所有进入stackIn的元素全部压入stackOut栈中(注意要判断out栈是否为空,为空元素才能入栈,out栈若不为空元素就入栈,则新入栈的元素会先出来)。
两点注意:
①进入stackIn的元素,要全部进入stackOut中。
②只有stackOut中没有元素时,元素才能进入stackOut中,否则会破坏出栈顺序。
实现四个函数:
push:直接stackIn.push(x)即可。
pop:首先调用dumpStackIn方法,若原out栈不为空,则直接返回原栈的栈顶,否则将in栈的元素压入out栈后返回栈顶元素。
peek:同pop。
empty:当stackIn与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();
}
public void dumpStackIn(){
//如果out里还有元素(非空),则in元素不入out栈 否则会破坏out栈原有出栈顺序,即新入的out元素比之前还没有出out栈的元素先出out栈
if(!stackOut.isEmpty()){
return;
}
//若out为空则可以入栈,将in里的所有元素都加入到out栈中
while(!stackIn.isEmpty()){
stackOut.push(stackIn.pop());
}
return;
}
}
225. 用队列实现栈
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
我看懂了解题思路,代码实现部分还有一些问题,下次补上。。
//1.9补充:
本题就是将一个队列q2视为辅助队列,用来实现q1正确的出栈顺序,入栈时进行操作,出栈只需要出q1存放的正确顺序的元素即可。
元素入队列时首先将元素存放在辅助队列q2中,若q1不为空,则将q1中所有元素加入到q2中。此时q1之前加入的元素就相当于q2后加入的元素,实现了先进后出。最后交换q1和q2。q1依旧代表正确顺序,q2为空。
class MyStack {
Queue<Integer> queue1; // 和栈中保持一样元素的队列
Queue<Integer> queue2; // 辅助队列
/** Initialize your data structure here. */
public MyStack() {
queue1 = new LinkedList<>();
queue2 = new LinkedList<>();
}
public void push(int x) {
queue2.offer(x);//先将元素存放在q2,暂时存放正确顺序
while(!queue1.isEmpty()){
queue2.offer(queue1.poll());//若q1非空,则将q1中的元素加入到q2中。此时q1之前入队列的元素变为q2后入队列的元素成为后出元素,实现了先进后出
}
Queue<Integer> temp;
temp=queue1;
queue1=queue2;
queue2=temp;//交换q1和q2两个队列,此时q1为正确出栈顺序(先进后出),q2为空
}
public int pop() {
return queue1.poll();
}
public int top() {
return queue1.peek();
}
public boolean empty() {
return queue1.isEmpty()&&queue2.isEmpty();
}
}
20. 有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
解题思路:括号匹配是使用栈解决的经典问题。由于栈是先进后出。因此可以让所有左括号入栈(入相应的右括号),然后最后入栈的左括号会最先进行匹配。
不匹配的三种情况:
①左括号多
②右括号多
③类型不匹配
让所有左括号入栈,若当前元素为右括号时,让相应的左括号(栈顶)出栈,若类型不匹配(③),则返回false;
若当前元素为右括号时栈为空(②),说明没有足够左括号匹配,返回false;
若所有元素入栈后栈不为空(①),说明没有足够右括号匹配,则返回false。
下面是我写的代码,还不是很优化:
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
if (s.length() % 2 != 0) {
return false;
}
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '(') {
stack.push(')');
}
else if (c == '[') {
stack.push(']');
}
else if (c == '{') {
stack.push('}');
}
if (c == ')') {
if (!stack.isEmpty()&&stack.pop() == ')') {
continue;
} else {
return false;
}
}
if (c == ']') {
if (!stack.isEmpty()&&stack.pop() == ']') {
continue;
} else {
return false;
}
}
if (c == '}') {
if (!stack.isEmpty()&&stack.pop() == '}') {
continue;
} else {
return false;
}
}
}
if (stack.isEmpty()) {
return true;
} else {
return false;
}
}
1047. 删除字符串中的所有相邻重复项
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
输入:"abbaca" 输出:"ca"
本题为匹配问题,栈的应用。
方法一:直接用栈解决(复杂度较高)
class Solution {
public String removeDuplicates(String s) {
Stack<Character> stack=new Stack<>();
for(int i=0;i<s.length();i++){
char c=s.charAt(i);
if(stack.isEmpty()||stack.peek()!=c){
stack.push(c);
}else if(stack.peek()==c){
stack.pop();
}
}
String ss="";
int size= stack.size();
for(int i=0;i<size;i++) {
ss += stack.pop();
}
return new StringBuffer(ss).reverse().toString();
}
}
方法二:用字符串模拟栈
该方法降低了复杂度,下面是我自己写的,由于时间不够了还没看优化后的。。下次补上!
StringBuffer sb = new StringBuffer(s);
int top = 0;
int len = sb.length();
for (int i = 0; i < len; i++) {
char t = sb.charAt(top);
if (i == 0 || (top != 0 && sb.charAt(top) != sb.charAt(top - 1))) {
top++;
} else if (top!=0 && sb.charAt(top) == sb.charAt(top - 1)) {
sb.deleteCharAt(top);
sb.deleteCharAt(top - 1);
top -= 1;
}else if(top==0){top++;}
}
return sb.toString();