Cracking coding interview(3.3)实现堆栈集合和popAt函数实现

copyright:CC150

3.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.

1.SetOfStacks1->通过定长数组实现子堆栈,popAt(int num)删除某个子堆栈的栈顶元素后,该子堆栈(并非最后一个栈)会通过操作,重新保持最大容量状态,popAt2(int num),删除该子栈顶(并非最后一个栈),该堆栈会保持当前的元素数目,不会维持最大容量状态。

2.SetOfStacks2->通过Node节点来实现子堆栈。popAt(int num)与popAt2(int num)实现原理同上。

import java.util.ArrayList;
import java.util.Scanner;

class SetOfStacks1{
	private ArrayList<int[]> list = new ArrayList<int[]>();
	private final int MAX_STACK_SIZE = 2;
	private int top = -1;
	
	public void push(int val){
		if(MAX_STACK_SIZE != 0){//no sense			
			if(list.size() == 0 || top == MAX_STACK_SIZE -1){
				//when perform popAt2(),use stack num [MAX_STACK_SIZE] store top stack num's value 
				list.add(new int[MAX_STACK_SIZE+1]);
				top = -1;
			}
			int[] s = list.get(list.size()-1);
			s[++top] = val;
			//used for perform popAt2()
			if(top == MAX_STACK_SIZE-1)
				s[MAX_STACK_SIZE] = top;
		}else{
			System.out.println("every substack holds max is zero");
		}
	}
	public int pop(){
		if(list.size() == 0 || top == -1){//top == -1 never access
			return Integer.MIN_VALUE;
		}
		System.out.print("<"+(list.size())+">");//display stack number
		int[] s = list.get(list.size()-1);
		int val = s[top];
		top--;
		if(top == -1){
			list.remove(list.size()-1);
			top = MAX_STACK_SIZE - 1;
		}
		return val;
	}
	public int pop2(){
		if(list.size() == 0 || top == -1){//top == -1 never access
			return Integer.MIN_VALUE;
		}
		System.out.print("<"+(list.size())+">");//display stack number
		int[] s = list.get(list.size()-1);
		int val = s[top];
		top--;
		if(top == -1){
			list.remove(list.size()-1);
			if(list.size() != 0){
				s = list.get(list.size()-1);
				top = s[MAX_STACK_SIZE];
			}
			//if wo wanna tp perform : top = s[MAX_STACK_SIZE-1]
		}
		return val;
	}
	//after popAt(i), stack i still keep filled, except for the last
	//maybe this idea is make better sense
	public int popAt(int num){
		if(num <= 0 || num > list.size())
			return Integer.MIN_VALUE;
		//stack's serial number from 1 start 
		int val = 0;
		int[] s = list.get(num-1);
		if(list.size() > num){
			val = s[MAX_STACK_SIZE-1];
			int[] next = null;
			int loop = 0;
			while(++num <= list.size()){
				next = list.get(num-1);
				s[MAX_STACK_SIZE-1] = next[0];
				if(num == list.size())
					loop = top+1;
				else
					loop = next.length-1;//next[MAX_STACK_SIZE] store the value of top
				for(int i=0;i < loop-1;i++)
					next[i] = next[i+1];
				s = next;
			}
		}else if(list.size() == num){
			val = s[top];
		}
		top--;
		if(top == -1){
			list.remove(list.size()-1);
			if(!empty())
				top = MAX_STACK_SIZE-1;
		}
		return val;
	}
	//After substack n execute popAt(), substack n couldn't keep filled
	//and if substack is pop to empties, it will be removed
	public int popAt2(int num){
	//for every substack, use extra space keep track of top
		if(num <= 0 || num > list.size())
			return Integer.MIN_VALUE;
		int[] s = list.get(num-1); 
		if(num < list.size()){
			s[MAX_STACK_SIZE]--;
			if(s[MAX_STACK_SIZE] == -1)
				list.remove(num-1);
			return s[s[MAX_STACK_SIZE]+1];
		}else{
			return pop();
		}	
	}
	public boolean empty(){
		if(list.size() == 0)
			return true;
		else
			return false;
	
	}
}
class SetOfStacks2{
	private int holds = 0;//record the number of elements that the last Stack has held
	private final int CAPACITY = 5;
	private ArrayList<Node> list = new ArrayList<Node>();
	class Node{
		int val;
		Node next;
		public Node(int val){
			this.val = val;
			this.next = next;
		}
	}
	public void push(int val){
		if(CAPACITY > 0 && holds <= CAPACITY){
			//case:holds->the number of sub stacks is zero 
			//case:holds == CAPACITY->the last substack is filled
			if(holds == 0 || holds == CAPACITY){
				list.add(new Node(val));
				holds = 0;
			}else{
				Node top = list.remove(list.size()-1);
				Node n = new Node(val);
				n.next = top;
				top = n;
				list.add(top);
			}					
			holds++;
		}
	}
	public int pop(){
		if(list.size() != 0){
			System.out.print("["+list.size()+"]");//
			Node top = list.remove(list.size()-1);
			Node n = top;
			/*
			for(Node p = top;p!=null;p=p.next)
				System.out.print("["+p.val+"]");
			*/
			top = top.next;
			holds--;
			if(holds != 0 && top != null){//enhance condition
				list.add(top);
//				System.out.println("top.val="+top.val);//
			}
			return n.val;
		}else{
			System.out.println("stack is empty!");
			return Integer.MIN_VALUE;
		}
	}	
	public int pop2(){
		if(list.size() != 0){
			System.out.print("["+list.size()+"]");//
			Node top = list.remove(list.size()-1);
			Node n = top;
			/*
			for(Node p = top;p!=null;p=p.next)
				System.out.print("["+p.val+"]");
			*/
			top = top.next;
			holds--;
			if(holds != 0 && top != null){//enhance condition
				list.add(top);
//				System.out.println("top.val="+top.val);//
			}else{
				if(list.size() != 0){
					top = list.get(list.size()-1);
					int counter = 0;
					for(Node p = top;p != null;p = p.next)
						counter++;
					holds = counter;
				}else{
					holds = 0;
				}
			}
			return n.val;
		}else{
			System.out.println("stack is empty!");
			return Integer.MIN_VALUE;
		}
	}
	//After substack n execute popAt(), substack n still keep filled
	public int popAt(int num){
		//num started from 1 
		if(num <= 0 || num > list.size()){
			System.out.println("substack isn't existed !");
			return Integer.MIN_VALUE;
		}else{
			if(num < list.size()){
				Node top = list.get(num-1);
				int val = top.val;
				Node n = null;
				top = top.next;
				//num->1  corresponding list.get(0)
				for(;num < list.size();){
					n = list.get(num);
					//the only element n of every sub stack is we wanted to fill the loss
					if(n.next == null){
						n.next = top;
						top = n;
						list.set(num-1, top);
						list.set(num, null);//n.next == null
						//the only element of last sub stack
						if(num == list.size()-1){
							list.remove(num);
							holds = CAPACITY;
							break;
						}
					}else{
						for(;n.next.next != null;n = n.next)
							;
						n.next.next = top;
						top = n.next;
						n.next = null;
						list.set(num-1, top);
						if(num == list.size()-1){
							holds--;
						}
					}
					//virables increasement
					top = list.get(num);
					num++;
				}
				return val;
			}else{
				return pop();
			}
		}
	}
	//After substack n execute popAt(), substack n couldn't keep filled
	//and if substack is pop to empties, it will be removed
	public int popAt2(int num){
		if(num <= 0 || num > list.size()){
			System.out.println("substack isn't existed !");
			return Integer.MIN_VALUE;
		}else{
			//the only question is :holds has changed, must be to 
			//keep synchronization with holds,that would influence
			//the performance of pop()
			Node top = list.get(num-1);
			int val = top.val;
			top = top.next;
			if(top == null)
				list.remove(num-1);
			else
				list.set(num-1, top);
			
			return val;
		}
	}
	public boolean empty(){
		if(list.size() == 0)
			return true;
		else
			return false;
	}

}


public class Solution{
	public static void main(String[] args){
	/*
		//test for SetOfStack1.popAt(int num)
		SetOfStacks1 sos1 = new SetOfStacks1();
		for(int i=1;i <= 20;i++)
			sos1.push(i);
		
		System.out.println("sos1.popAt(2)="+sos1.popAt(2));//
		for(;!sos1.empty();)
			System.out.print(sos1.pop()+" ");
		System.out.println();
	*/	
	/*
		//test for SetOfStack1.popAt2(int num)
		SetOfStacks1 sos1 = new SetOfStacks1();
		for(int i=1;i <= 20;i++)
			sos1.push(i);
		
		System.out.println("sos1.popAt2(2)="+sos1.popAt2(2));//
		for(;!sos1.empty();)
			System.out.print(sos1.pop2()+" ");
		System.out.println();	
	*/
	/*
		//test for SetOfStack2.popAt(int num)
		SetOfStacks2 sos2 = new SetOfStacks2();
		for(int i=1;i <= 20;i++)
			sos2.push(i);
			
		System.out.println("sos2.popAt(2)="+sos2.popAt(2));//
		for(;!sos2.empty();)
			System.out.print(sos2.pop()+" ");
		System.out.println();
	*/	
		//test for SetOfStack2.popAt2(int num)
		SetOfStacks2 sos2 = new SetOfStacks2();
		for(int i=1;i <= 20;i++)
			sos2.push(i);
			
		System.out.println("sos2.popAt(2)="+sos2.popAt2(2));//
		System.out.println("sos2.popAt(2)="+sos2.popAt2(2));//
		System.out.println("sos2.popAt(2)="+sos2.popAt2(2));//
		System.out.println("sos2.popAt(2)="+sos2.popAt2(2));//
		for(;!sos2.empty();)
			System.out.print(sos2.pop2()+" ");
		System.out.println();
	
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值