1、给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
1、左括号必须用相同类型的右括号闭合。
2、左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
思路:
我们可以使用栈来判断字符串是否有效。
先定义一个栈,从所输入的第一个字符串开始判断,如果遇到左括号,全部入栈,而如果遇到了右括号,首先判断当前栈是否为空。
如果栈为空的时候遇到了右括号,说明不匹配;如果栈不为空遇到了右括号,那么首先拿出栈顶元素和这个右括号进行匹配,如果不是同一对括号,就比如说“(”遇到了“]”,很明显这也是不匹配的。就这样一直判断,所有字符串判断完毕,而且栈也为空了,说明就是这串字符串就是匹配的。
看代码:
public boolean isValid(String s) {
Stack<Character> stack = new Stack<Character>();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
switch (ch) {
case '(':
case '[':
case '{':
stack.push(ch);
break;
case ')':
case ']':
case '}': {
if (stack.isEmpty()) {
return false;
}
char left = stack.pop();
if (!((left == '(' && ch == ')') || (left == '[' && ch == ']') || (left == '{' && ch == '}'))) {
return false;
}
break;
}
default:
break;
}
}
if (stack.isEmpty()) {
return true;
} else {
return false;
}
}
2、使用栈实现队列
具体操作:
push(x) – 将一个元素放入队列的尾部。
pop() – 从队列首部移除元素。
peek() – 返回队列首部的元素。
empty() – 返回队列是否为空
思路:
push操作
很简单,将一个元素放入队列的尾部就是进行普通的入栈操作。
pop操作
相对来说麻烦一点点,从队列的首部移除元素,我们可以定义两个栈来实现,一个in栈用来保存所有入栈的数据,一个out栈用来保存所有出栈出掉的数据。如果out栈为空,先从in栈出掉一个数据,再把出掉的这个数据进行入栈操作放到out栈中,这样一来,我们再从out栈出数据就相当于实现了从队列的首部移除数据。
peek操作
和上面说过的pop操作基本上是一样的,只是peek操作不用出掉数据,只是查看out栈的栈顶元素,这个就是队列首部的元素。
empty操作
判断队列是否为空,这需要in栈和out栈同时为空,否则就不能说明队列是空的。
具体代码如下:
class MyQueue {
Stack<Integer> in;
Stack<Integer> out;
/**
* Initialize your data structure here.
*/
public MyQueue() {
in = new Stack<Integer>();
out = new Stack<Integer>();
}
/**
* Push element x to the back of queue.
*/
public void push(int x) {
in.push(x);
}
/**
* Removes the element from in front of queue and returns that element.
*/
public int pop() {
if (out.isEmpty()) {
while (!in.isEmpty()) {
int v = in.pop();
out.push(v);
}
}
int v = out.pop();
return v;
}
/**
* Get the front element.
*/
public int peek() {
if (out.isEmpty()) {
while (!in.isEmpty()) {
int v = in.pop();
out.push(v);
}
}
int v = out.peek();
return v;
}
/**
* Returns whether the queue is empty.
*/
public boolean empty() {
return in.isEmpty() && out.isEmpty();
}
}
3、实现一个最小栈
push(x) – 将元素 x 推入栈中。
pop() – 删除栈顶的元素。
top() – 获取栈顶元素。
getMin() – 检索栈中的最小元素。
思路:
实现一个最小栈是典型的以空间换时间
问题。
我们需要定义两个栈,一个是normal栈,正常保存数据,一个min栈,用来保存当前栈中最小的数据。
往normal栈中放数据的同时,需要判断当前栈中最小的数据。第一次插入数据的时候,这个数据就是最小值,直接放入min栈。之后每一次都需要进行判断,如果min栈中栈顶元素比新插入的这个数据大,那么说明新插入的这个数据是最小值,把这个数据插入到min栈中,否则的话,将min栈的栈顶元素重新放入min栈中,代表当前栈中最小值依然是这个数据。
其它三个操作比较简单,代码直接就能看懂,注意删除元素的时候,两个栈的栈顶元素都要删除。
具体代码如下:
class MinStack {
Stack<Integer> min;
Stack<Integer> normal;
/** initialize your data structure here. */
public MinStack() {
this.min = new Stack<Integer>();
this.normal = new Stack<Integer>();
}
public void push(int x) {
this.normal.push(x);
if (this.min.isEmpty() || this.min.peek()>=x){
this.min.push(x);
}else {
this.min.push(this.min.peek());
}
}
public void pop() {
this.normal.pop();
this.min.pop();
}
public int top() {
return this.normal.peek();
}
public int getMin() {
return this.min.peek();
}
}