Cracking the coding interview--Q3.3

原文:

Imagine a (literal) stack of plates. If the stack gets too high, it might topple. Therefore, in real life, we would likely start a new stack when the previous stack exceeds some threshold. Implement a data structure SetOfStacks that mimics this. SetOfStacks should be composed of several stacks, and should create a new stack once the previous one exceeds capacity. SetOfStacks.push() and SetOfStacks.pop() should behave identically to a single stack (that is, pop() should return the same values as it would if there were just a single stack).

FOLLOW UP

Implement a function popAt(int index) which performs a pop operation on a specific sub-stack.

译文:

栈就像叠盘子,当盘子叠得太高时,就会倾斜倒下。因此,在真实的世界中,当一叠盘子 (栈)超过了一定的高度时,我们就会另起一堆,再从头叠起。实现数据结构SetOfStacks 来模拟这种情况。SetOfStacks由几个栈组成,当前一栈超出容量时,需要创建一个新的栈 来存放数据。SetOfStacks.push()和SetOfStacks.pop()的行为应当和只有一个栈时 表现的一样。

进一步地,

实现函数popAt(int index)在指定的子栈上进行pop操作。


首先当不考虑进一步的操作,popAt(int index)时。 单纯考虑入栈出栈操作。每个子栈用相等长度数组存储栈元素,当一个栈数组存满元素,则记录下一个栈

可以使用变量curStack 记录当前所在栈编号。

如果元素入栈,首先判断整个栈是否满栈,当整个栈满栈,则提示栈满。

	/**
	 * 是否栈满
	 * 栈满条件为子栈为最大且同时也满栈
	 * @return
	 */
	public boolean isFull() {
		return curStack == (childStack-1) && stack[curStack].isFull();
	}

否则入栈,入栈则需要先判断当前子栈是否已经满栈,如果当前子栈已经满栈,则curStack++。进入下一个子栈,如果当前子栈不满栈,则元素入栈stack[curStack].push(data);

如果元素出栈,则首先判断是否整个栈栈空,栈空则提示栈空。

	/**
	 * 是否栈空
	 * 栈空条件为子栈是否最小且同时为空
	 * @return
	 */
	public boolean isEmpty() {
		return curStack == 0 && stack[curStack].isEmpty();
	}


如果栈不空,则出栈,如果子栈为空,则curStack--进入前一个子栈获取元素。

package chapter_3_StacksandQueues;

/**
 * @author LiangGe
 * 栈的基本操作
 */
class Stack_3 {
	private int size;
	private int stack[];
	private int top = -1;
	
	public Stack_3(int size) {
		this.size = size;
		stack = new int[size];
		top = -1;
	}
	
	public boolean isFull() {
		return top == (size-1);
	}
	
	public boolean isEmpty() {
		return top == -1;
	}
	
	public void push(int data) {
		if(isFull()) {
			//System.out.println("Stack is full!");
			return;
		}
		stack[++top] = data;
	}
	
	public void pop() {
		if(isEmpty()) {
			//System.out.println("Stack is empty!");
			return;
		}
		top --;
	}
	
	public int top() {
		if(isEmpty()) {
			//System.out.println("Stack is empty!");
			return -1;
		}
		return stack[top--];
	}
	
}

/**
 * @author LiangGe
 * 大栈操作
 */
class SetOfStacks{
	private int childStack;
	private Stack_3 stack[];
	private int curStack;
	
	public SetOfStacks(int size) {
		childStack = size;
		stack = new Stack_3[childStack];
		for(int i=0; i<childStack; i++) {
			stack[i] = new Stack_3(childStack);
		}
		curStack = 0;
	}
	
	/**
	 * 是否栈满
	 * 栈满条件为子栈为最大且同时也满栈
	 * @return
	 */
	public boolean isFull() {
		return curStack == (childStack-1) && stack[curStack].isFull();
	}
	
	/**
	 * 是否栈空
	 * 栈空条件为子栈是否最小且同时为空
	 * @return
	 */
	public boolean isEmpty() {
		return curStack == 0 && stack[curStack].isEmpty();
	}
	
	public void push(int data) {
		if(isFull()) {
			System.out.println("Stack is full!");
			return;
		}
		
		if(stack[curStack].isFull()) {
			curStack ++;
		}
		
		stack[curStack].push(data);
	}
	
	public void pop() {
		if(isEmpty()) {
			System.out.println("Stack is empty!");
			return;
		}
		if(stack[curStack].isEmpty()) {
			curStack --;
		}
		stack[curStack].pop();
	}
	
	public int top() {
		if(isEmpty()) {
			System.out.println("Stack is empty!");
			return -1;
		}
		if(stack[curStack].isEmpty()) {
			curStack --;
		}
		return stack[curStack].top();
	}
}

/**
 * @author LiangGe
 *
 * 栈就像叠盘子,当盘子叠得太高时,就会倾斜倒下。因此,在真实的世界中,当一叠盘子 (栈)超过了一定的高度时,我们就会另起一堆,再从头叠起。
 * 实现数据结构SetOfStacks 来模拟这种情况。SetOfStacks由几个栈组成,当前一栈超出容量时,需要创建一个新的栈 来存放数据。
 * SetOfStacks.push()和SetOfStacks.pop()的行为应当和只有一个栈时 表现的一样。
 *
 */
public class Question_3_3 {
	public static void main(String args[]) {
		SetOfStacks setOfSatacks = new SetOfStacks(3);
		
		for(int i=0; i<10; i++) {
			setOfSatacks.push(i);
		}
		
		for(int i=0; i< 11 ;i++) {
			int top = setOfSatacks.top();
			if(top != -1) {
				System.out.println("Top stack :" + top);
			}
		}
	}
}


如果考虑进一步的操作popAt(int index)时,

	public int top() {
		if(isEmpty()) {
			System.out.println("Stack is empty!");
			return -1;
		}
		while(stack[curStack].isEmpty()) {
			curStack --;
		}
		
		return stack[curStack].top();
	}
	
	public void pop() {
		if(isEmpty()) {
			System.out.println("Stack is empty!");
			return;
		}
		while(stack[curStack].isEmpty()) {
			curStack --;
		}
		stack[curStack].pop();
	}
	
	public void popAt(int index) {
		stack[index].pop();
	}


则如果考虑中间栈元素需要出栈,则会使得中间元素栈内有空闲位置,此时如果考虑牺牲空间问题,则空闲位置继续空闲。

则此时在上述问题中只需要考虑出栈操作,因为入栈操作没有变化,只是出栈操作需要判断。

如果元素出栈,则首先判断大栈是否为空,如果不为空则出栈,此时出栈首先判断当前子栈是否为空,为空则需要while循环往前查找

下一个非空子栈。

		while(stack[curStack].isEmpty()) {
			curStack --;
		}

所需只需要在出栈和获取栈顶元素代码出进行修改即可

	public int top() {
		if(isEmpty()) {
			System.out.println("Stack is empty!");
			return -1;
		}
		while(stack[curStack].isEmpty()) {
			curStack --;
		}
		
		return stack[curStack].top();
	}
	
	public void pop() {
		if(isEmpty()) {
			System.out.println("Stack is empty!");
			return;
		}
		while(stack[curStack].isEmpty()) {
			curStack --;
		}
		stack[curStack].pop();
	}
	
	public void popAt(int index) {
		stack[index].pop();
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值