题目:
设想有一堆盘子,堆得太高可能会倒下来,因此,在现实生活中,盘子堆到一定高度时,我们就会另外堆一堆盘子。请实现数据结构SetOfStacks,模拟这种行为。SetOfStacks应该由多个栈组成,并且在一个栈堆满时新建一个栈。
此外,push和pop要和只有一个栈的情况一致。另外需要实现一个popAt(index)方法,根据指定的子栈,执行pop操作,pop之后还要维持栈结构。
代码
package test1;
import java.util.ArrayList;
public class SetOfStacks2 {
private int HIGHT = 3;
// 存放已经放满的 stack
public ArrayList<ArrayList<Integer>> stacks;
// 当前还在用,没有满的 stack
public ArrayList<Integer> currStack;
public SetOfStacks2() {
stacks = new ArrayList<>();
currStack = new ArrayList<>();
}
public Integer push(Integer item) {
// 每次push前检查 currStack,如果已经放满,则加入的 stacks,然后新建一个stack
if (currStack.size() == HIGHT) {
stacks.add(currStack);
currStack = new ArrayList<>();
}
currStack.add(item);
return item;
}
public Integer pop() {
return pop(currStack);
}
private Integer pop(ArrayList<Integer> theStack) {
// 每次 pop 之前先检查 currStack是否为空;如果为空,则从stacks中拿一个stack出来
if (theStack.size() == 0) {
theStack = stacks.get(stacks.size() - 1);
stacks.remove(stacks.size() - 1);
}
int index = theStack.size() - 1;
Integer popItem = theStack.get(index);
theStack.remove(index);
return popItem;
}
/**
* stack的编号方式是:0,1,……,n,currStack. 在指定编号的stack上做pop操作,然后对后面的stack进行维护,不浪费空间
*/
public Integer popAt(int index) throws Exception {
if (index >= stacks.size()) {
throw new Exception("The index is out of boundary!");
}
ArrayList<Integer> theStack = stacks.get(index);
Integer popItem = pop(theStack);
int stacksNum = stacks.size();
ArrayList<Integer> s1, s2;
for (int i = index; i < stacksNum; i++) {
s1 = stacks.get(i);
if (i == stacksNum - 1) {
s2 = currStack;
if (currStack.isEmpty()) {
currStack = s1;
return popItem;
}
} else {
s2 = stacks.get(i + 1);
}
move(s1, s2);
}
return popItem;
}
/**
* 将s2的底部元素移到s1的顶部
*/
private boolean move(ArrayList<Integer> s1, ArrayList<Integer> s2) {
if (s2.isEmpty()) {
return false;
}
s1.add(s2.remove(0));
return true;
}
public void display() {
int s_stacks = stacks.size();
System.out.printf("The size of stacks is : %d\n", s_stacks);
ArrayList<Integer> tmp;
for (int i = 0; i < s_stacks; i++) {
tmp = stacks.get(i);
for (Integer integer : tmp) {
System.out.printf("%-3s ", integer.toString());
}
System.out.print("|| ");
}
System.out.printf("\nThe size of current stack is : %d\n", currStack.size());
for (Integer integer : currStack) {
System.out.printf("%-3s ", integer.toString());
}
System.out.println("\n");
}
}
测试
public static void main(String[] args) {
SetOfStacks2 ss = new SetOfStacks2();
for (int i = 0; i < 20; i++) {
ss.push(i);
}
ss.display();
try {
ss.popAt(2);
ss.display();
ss.popAt(3);
ss.display();
ss.popAt(2);
ss.display();
} catch (Exception e) {
e.printStackTrace();
}
}
The size of stacks is : 6
0 1 2 || 3 4 5 || 6 7 8 || 9 10 11 || 12 13 14 || 15 16 17 ||
The size of current stack is : 2
18 19
The size of stacks is : 6
0 1 2 || 3 4 5 || 6 7 9 || 10 11 12 || 13 14 15 || 16 17 18 ||
The size of current stack is : 1
19
The size of stacks is : 6
0 1 2 || 3 4 5 || 6 7 9 || 10 11 13 || 14 15 16 || 17 18 19 ||
The size of current stack is : 0
The size of stacks is : 6
0 1 2 || 3 4 5 || 6 7 10 || 11 13 14 || 15 16 17 || 18 19 ||
The size of current stack is : 2
18 19