一、双栈队列
题型:
编写一个类,只能用两个栈结构实现队列结构,支持队列的基本操作。
思路:
这种题目的实现思路为,首先创建两个栈,一个是stackPush,一个是stackPop,因为队列结构的要求是数据是先进先出,但是栈结构的要求是先进后出,那么要用栈结构实现队列结构就需要将stackPush中的元素倒入到stackPop栈中,弹出时再弹出stackPop中的元素,这样先进的元素就先出了。
在这个过程中,为了不出错,我们要注意两点,第一点是stackPush栈向stackPop栈中倒入元素时,一定要将元素全部倒入进去;第二点是stackPop不为空时才将stackPush栈中的数据倒入到stackPop中,否则会出错。
代码举例:
import java.util.*;
public class TwoStack {
public int[] twoStack(int[] ope, int n) {
// write code here
Stack<Integer> push = new Stack<Integer>();
Stack<Integer> pop = new Stack<Integer>();
//创建index表示将push中的元素全部放入pop
int index = 0;
for(int i=0;i<n;i++){
if(ope[i] != 0){
push.push(ope[i]);
}else{
index ++;
}
}
//将push中的元素放入pop
while(!push.empty()){
pop.push(push.pop());
}
int [] popArr = new int[index];
int k = 0;
while(index >0){
popArr[k++] = pop.pop();
index--;
}
return popArr;
}
}
二、栈的反转练习
题型:
实现一个栈的逆序,但是只能用递归函数和这个栈本身的操作来实现而不能自己申请另外的数据结构。
思路:
面对这个问题,我们需要实现两个递归函数,第一个递归函数A,我们需要通过A函数获取到栈中的栈底元素并删除栈底元素,第二个函数需要通过调用A函数,获取到栈底元素,然后每一层返回时,将这一层获得的栈底元素压入栈中。
代码举例:
import java.util.*;
public class StackReverse {
public int[] reverseStack(int[] A, int n) {
// write code here
Stack<Integer> sta = new Stack<Integer>();
for(int i=0;i<n;i++){
sta.push(A[i]);
}
reverse(sta);
for(int j=n-1;j>=0;j--){
A[j] = sta.pop();
}
return A;
}
public void reverse(Stack<Integer> x){
if(x.isEmpty()){
return;
}else{
int i = get(x);
reverse(x);
x.push(i);
}
}
//创建方法获取并删除栈底元素
public int get(Stack<Integer> x){
int result = x.pop();
if(x.isEmpty()){
return result;
}else{
int last = get(x);
x.push(result);
return last;
}
}
}
三、双栈排序
题意:
一个栈中数据类型为整型,现在想将该栈从顶到底按从大到小排序,只许申请一个栈,除此之外可以申请新的变量,但不能申请额外的数据结构。
思路:
我们可以申请一个辅助栈help,将想要排序的栈顶元素current弹出并与help的栈顶元素比较,如果小于等于help的栈顶元素,则将元素压入help栈,如果大于,则将help中的元素一次弹出并压入目标栈中,再将current压入help栈中。以此类推,最后当目标栈空时,将help栈中的元素全部弹出并压入目标栈。
代码举例:
import java.util.*;
public class TwoStacks {
public ArrayList<Integer> twoStacksSort(int[] numbers) {
// write code here
int[] help = new int[numbers.length];
int n = numbers.length;
int i = 0, j = n;//栈的当前指针
int cur;
while (i < n) {
//++为出栈,--为进栈
//弹出栈中的第一个元素,下移index
cur = numbers[i++];
if (j == n) {
// 将弹出元素压入help栈顶
help[--j] = cur;
} else if (cur <= help[j]) {
// 将弹出元素压入help栈顶
help[--j] = cur;
} else if (cur > help[j]) {
// 弹出help栈中的元素,并将其压入到主栈栈顶,直到cur小于等于help栈顶元素
while (j < n && cur > help[j]) {
numbers[--i] = help[j++];
}
// 将弹出元素压入help栈顶
help[--j] = cur;
}
}
numbers[0] = help[n - 1];
ArrayList<Integer> list = new ArrayList<>();
for (int m = 0; m < n; m++) {
list.add(help[n - m - 1]);
}
return list;}
}