1. 括号匹配问题。
package 课堂代码.课件练习.栈和队列.有效的括号;
import java.util.Stack;
public class Test {
public static void main(String[] args) {
String s = "()";
System.out.println(isValid(s));
}
public static boolean isValid(String s) {
if (s.length() % 2 == 1) {
return false;
}
Stack<String> stack = new Stack<>();
String[] split = s.split("");
for (int i = 0; i < split.length; i++) {
switch (split[i]) {
case ")":
if (stack.empty() || !stack.pop().equals("(")) {
return false;
}
break;
case "]":
if (stack.empty() || !stack.pop().equals("[")) {
return false;
}
break;
case "}":
if (stack.empty() || !stack.pop().equals("{")) {
return false;
}
break;
default:
stack.push(split[i]);
}
}
return stack.empty();
}
}
效率偏低,
if (s.length() % 2 == 1) {
return false;
}
HashMap<Character, Character> hashMap = new HashMap<>();
hashMap.put(')','(');
hashMap.put(']','[');
hashMap.put('}','{');
Stack<Character> stack = new Stack<>();
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
if(hashMap.containsKey(chars[i])){
if(stack.empty() || stack.pop() != hashMap.get(chars[i])){
return false;
}
}else {
stack.push(chars[i]);
}
}
return stack.empty();
参考题解进行了改善,使用了hashmap存储了括号的种类,用栈保证括号顺序的正确.从而简化了代码
注意事项 : && 和 || 作为短路运算符,我们在if判断中可以将stack.empty方法放在||左边,如果检查为空就不会对栈进行操作,从而导致程序报错.
if (s.length() % 2 == 1) {
return false;
}
Stack<String> stack = new Stack<>();
String[] split = s.split("");
//遇见左括号向入栈对应括号,在遇见右括号的时候进行比较
for (String str :
split) {
if ("(".equals(str)) {
stack.push(")");
continue;
} else if ("[".equals(str)) {
stack.push("]");
continue;
} else if ("{".equals(str)) {
stack.push("}");
continue;
}
if (stack.empty() || !stack.pop().equals(str)) {
return false;
}
}
return stack.empty();
2. 用队列实现栈。
package 课堂代码.课件练习.栈和队列.用队列实现栈;
public class Test {
public static void main(String[] args) {
MyStack myStack = new MyStack();
for (int i = 0; i < 2; i++) {
myStack.push(i);
}
System.out.println(myStack.top());
System.out.println(myStack.empty());
System.out.println(myStack.pop());
System.out.println(myStack.pop());
System.out.println(myStack.pop());
}
}
class MyStack {
private int[] date;
int size;
/**
* Initialize your data structure here.
*/
public MyStack() {
date = new int[10];
size = 0;
}
/**
* Push element x onto stack.
*/
public void push(int x) {
//扩容
if(size >= date.length){
int[] ints = new int[date.length + (date.length >> 1)];
System.arraycopy(date,0,ints,0,size);
date = ints;
}
date[size++] = x;
}
/**
* Removes the element on top of the stack and returns that element.
*/
public int pop() {
if(size == 0){
return -1;
}
return date[--size];
}
/**
* Get the top element.
*/
public int top() {
if(size == 0){
return -1;
}
return date[size-1];
}
/**
* Returns whether the stack is empty.
*/
public boolean empty() {
return size == 0;
}
}
/**
* 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();
*/
最后发现要用队列实现(汗)
class MyStack {
Queue<Integer> queue;
/**
* Initialize your data structure here.
*/
public MyStack() {
queue = new LinkedList<Integer>();
}
/**
* Push element x onto stack.
*/
public void push(int x) {
queue.offer(x);
for (int i = 0; i < queue.size() - 1; i++) {
queue.offer(queue.poll());
}
}
/**
* Removes the element on top of the stack and returns that element.
*/
public int pop() {
return queue.poll();
}
/**
* Get the top element.
*/
public int top() {
return queue.peek();
}
/**
* Returns whether the stack is empty.
*/
public boolean empty() {
return queue.isEmpty();
}
}
3. 用栈实现队列。
class MyQueue {
Stack<Integer> stack;
/**
* Initialize your data structure here.
*/
public MyQueue() {
stack = new Stack<Integer>();
}
/**
* Push element x to the back of queue.
*/
public void push(int x) {
//栈的特点是先入后出,要实现队列的特点,先入先出.
//每一个入栈的时候,我们可以将之前的全部出栈并
//
int[] ints = new int[100];
int i = 0;
for (; !stack.empty(); i++) {
ints[i] = stack.pop();
}
stack.push(x);
for (; i >0; i--) {
stack.push(ints[i-1]);
}
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
return stack.pop();
}
/** Get the front element. */
public int peek() {
return stack.peek();
}
/** Returns whether the queue is empty. */
public boolean empty() {
return stack.empty();
}
}
题解建议使用两个栈
4. 实现一个最小栈。
class MinStack {
Stack<Integer> stack;
Stack<Integer> minstack;
/**
* initialize your data structure here.
*/
public MinStack() {
//题解采用辅助栈的做法
stack = new Stack<>();
minstack = new Stack<>();
minstack.push(Integer.MAX_VALUE);
}
public void push(int x) {
stack.push(x);
if(!minstack.empty() && x<=minstack.peek() ){
minstack.push(x);
}
}
public void pop() {
int ret = stack.pop();
if(!minstack.empty() && ret == minstack.peek()){
minstack.pop();
}
}
public int top() {
return stack.peek();
}
public int getMin() {
return minstack.peek();
}
}
5. 设计循环队列。
class MyCircularQueue {
private int[] date;
private int head = 0;
private int tail = 0;
private int size = 0;
//MyCircularQueue(k): 构造器,设置队列长度为 k 。
public MyCircularQueue(int k) {
date = new int[k];
}
//enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
public boolean enQueue(int value) {
if (size == date.length) {
return false;
}
date[tail++] = value;
if (tail == date.length) {
tail = 0;
}
size++;
return true;
}
//deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
public boolean deQueue() {
if (size == 0) {
return false;
}
head++;
if (head == date.length) {
head = 0;
}
size--;
return true;
}
//Front: 从队首获取元素。如果队列为空,返回 -1 。
public int Front() {
if(size == 0){
return -1;
}
return date[head];
}
//Rear: 获取队尾元素。如果队列为空,返回 -1 。
public int Rear() {
if(size == 0){
return -1;
}
return date[(head+size-1 )% date.length];
}
//isEmpty(): 检查循环队列是否为空。
public boolean isEmpty() {
return size == 0;
}
//isFull(): 检查循环队列是否已满。
public boolean isFull() {
return size == date.length;
}
}
使用添加过程最后一个的时候会检测tail++后已经 == 数组长度了,所以将tail重置到0,但是在下一步Rear要显示尾部元素的时候.因为tail已经变化为0,所以我们可以使用head+当前元素数量size,对数组长度取余就是tail的位置.
同时我们可以使用
date[((head +size)%date.length)] = value;
head和数据长度这样的数据代替tail.