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.
You should delete the sub-stack when it becomes empty. pop, popAt should return -1 when there's no element to pop.
We can use a list of stacks \(stk\) to simulate this process, initially \(stk\) is empty.
When the push method is called, if \(cap\) is 0, return directly. Otherwise, if \(stk\) is empty or the length of the last stack in \(stk\) is greater than or equal to \(cap\), then create a new stack. Then add the element \(val\) to the last stack in \(stk\). The time complexity is \(O(1)\).
When the pop method is called, return the result of popAt(|stk| - 1). The time complexity is \(O(1)\).
When the popAt method is called, if \(index\) is not in the range \([0, |stk|)\), return -1. Otherwise, return the top element of \(stk[index]\) and pop it out. If \(stk[index]\) is empty after popping, remove it from \(stk\). The time complexity is \(O(1)\).
The space complexity is \(O(n)\), where \(n\) is the number of elements.
classStackOfPlates:def__init__(self,cap:int):self.cap=capself.stk=[]defpush(self,val:int)->None:ifself.cap==0:returnifnotself.stkorlen(self.stk[-1])>=self.cap:self.stk.append([])self.stk[-1].append(val)defpop(self)->int:returnself.popAt(len(self.stk)-1)defpopAt(self,index:int)->int:ans=-1if0<=index<len(self.stk):ans=self.stk[index].pop()ifnotself.stk[index]:self.stk.pop(index)returnans# Your StackOfPlates object will be instantiated and called as such:# obj = StackOfPlates(cap)# obj.push(val)# param_2 = obj.pop()# param_3 = obj.popAt(index)
classStackOfPlates{privateList<Deque<Integer>>stk=newArrayList<>();privateintcap;publicStackOfPlates(intcap){this.cap=cap;}publicvoidpush(intval){if(cap==0){return;}if(stk.isEmpty()||stk.get(stk.size()-1).size()>=cap){stk.add(newArrayDeque<>());}stk.get(stk.size()-1).push(val);}publicintpop(){returnpopAt(stk.size()-1);}publicintpopAt(intindex){intans=-1;if(index>=0&&index<stk.size()){ans=stk.get(index).pop();if(stk.get(index).isEmpty()){stk.remove(index);}}returnans;}}/** * Your StackOfPlates object will be instantiated and called as such: * StackOfPlates obj = new StackOfPlates(cap); * obj.push(val); * int param_2 = obj.pop(); * int param_3 = obj.popAt(index); */
classStackOfPlates{public:StackOfPlates(intcap){this->cap=cap;}voidpush(intval){if(!cap){return;}if(stk.empty()||stk.back().size()>=cap){stk.emplace_back(stack<int>());}stk.back().push(val);}intpop(){returnpopAt(stk.size()-1);}intpopAt(intindex){intans=-1;if(index>=0&&index<stk.size()){ans=stk[index].top();stk[index].pop();if(stk[index].empty()){stk.erase(stk.begin()+index);}}returnans;}private:intcap;vector<stack<int>>stk;};/** * Your StackOfPlates object will be instantiated and called as such: * StackOfPlates* obj = new StackOfPlates(cap); * obj->push(val); * int param_2 = obj->pop(); * int param_3 = obj->popAt(index); */
typeStackOfPlatesstruct{stk[][]intcapint}funcConstructor(capint)StackOfPlates{returnStackOfPlates{[][]int{},cap}}func(this*StackOfPlates)Push(valint){ifthis.cap==0{return}iflen(this.stk)==0||len(this.stk[len(this.stk)-1])>=this.cap{this.stk=append(this.stk,[]int{})}this.stk[len(this.stk)-1]=append(this.stk[len(this.stk)-1],val)}func(this*StackOfPlates)Pop()int{returnthis.PopAt(len(this.stk)-1)}func(this*StackOfPlates)PopAt(indexint)int{ans:=-1ifindex>=0&&index<len(this.stk){t:=this.stk[index]ans=t[len(t)-1]this.stk[index]=this.stk[index][:len(t)-1]iflen(this.stk[index])==0{this.stk=append(this.stk[:index],this.stk[index+1:]...)}}returnans}/** * Your StackOfPlates object will be instantiated and called as such: * obj := Constructor(cap); * obj.Push(val); * param_2 := obj.Pop(); * param_3 := obj.PopAt(index); */
classStackOfPlates{privatecap:number;privatestacks:number[][];constructor(cap:number){this.cap=cap;this.stacks=[];}push(val:number):void{if(this.cap===0){return;}constn=this.stacks.length;conststack=this.stacks[n-1];if(stack==null||stack.length===this.cap){this.stacks.push([val]);}else{stack.push(val);}}pop():number{constn=this.stacks.length;if(n===0){return-1;}conststack=this.stacks[n-1];constres=stack.pop();if(stack.length===0){this.stacks.pop();}returnres;}popAt(index:number):number{if(index>=this.stacks.length){return-1;}conststack=this.stacks[index];constres=stack.pop();if(stack.length===0){this.stacks.splice(index,1);}returnres;}}/** * Your StackOfPlates object will be instantiated and called as such: * var obj = new StackOfPlates(cap) * obj.push(val) * var param_2 = obj.pop() * var param_3 = obj.popAt(index) */
classStackOfPlates{privatevarstacks:[[Int]]privatevarcap:Intinit(_cap:Int){self.cap=capself.stacks=[]}funcpush(_val:Int){ifcap==0{return}ifstacks.isEmpty||stacks.last!.count>=cap{stacks.append([])}stacks[stacks.count-1].append(val)}funcpop()->Int{returnpopAt(stacks.count-1)}funcpopAt(_index:Int)->Int{guardindex>=0,index<stacks.count,!stacks[index].isEmptyelse{return-1}letvalue=stacks[index].removeLast()ifstacks[index].isEmpty{stacks.remove(at:index)}returnvalue}}/** * Your StackOfPlates object will be instantiated and called as such: * let obj = new StackOfPlates(cap); * obj.push(val); * let param_2 = obj.pop(); * let param_3 = obj.popAt(index); */