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); */