题目如下:

You have an infinite number of stacks arranged in a row and numbered (left to right) from 0, each of the stacks has the same maximum capacity.

Implement the DinnerPlates class:

  • DinnerPlates(int capacity) Initializes the object with the maximum capacity of the stacks.
  • void push(int val) pushes the given positive integer val into the leftmost stack with size less than capacity.
  • int pop() returns the value at the top of the rightmost non-empty stack and removes it from that stack, and returns -1 if all stacks are empty.
  • int popAtStack(int index) returns the value at the top of the stack with the given index and removes it from that stack, and returns -1 if the stack with that given index is empty.

Example:

Input:
["DinnerPlates","push","push","push","push","push","popAtStack","push","push","popAtStack","popAtStack","pop","pop","pop","pop","pop"]
[[2],[1],[2],[3],[4],[5],[0],[20],[21],[0],[2],[],[],[],[],[]]
Output:
[null,null,null,null,null,null,2,null,null,20,21,5,4,3,1,-1] Explanation:
DinnerPlates D = DinnerPlates(2); // Initialize with capacity = 2
D.push(1);
D.push(2);
D.push(3);
D.push(4);
D.push(5); // The stacks are now: 2  4
  1  3  5
﹈ ﹈ ﹈
D.popAtStack(0); // Returns 2. The stacks are now:  4
  1  3  5
﹈ ﹈ ﹈
D.push(20); // The stacks are now: 20 4
  1  3  5
﹈ ﹈ ﹈
D.push(21); // The stacks are now: 20 4 21
  1  3  5
﹈ ﹈ ﹈
D.popAtStack(0); // Returns 20. The stacks are now: 4 21
  1  3  5
﹈ ﹈ ﹈
D.popAtStack(2); // Returns 21. The stacks are now: 4
  1  3  5
﹈ ﹈ ﹈
D.pop() // Returns 5. The stacks are now: 4
  1  3
﹈ ﹈
D.pop() // Returns 4. The stacks are now: 1  3
﹈ ﹈
D.pop() // Returns 3. The stacks are now: 1

D.pop() // Returns 1. There are no stacks.
D.pop() // Returns -1. There are still no stacks.

Constraints:

  • 1 <= capacity <= 20000
  • 1 <= val <= 20000
  • 0 <= index <= 100000
  • At most 200000 calls will be made to pushpop, and popAtStack.

解题思路:本题我用了三个list,一个是stack_list,保存所以的stack信息;一个是nonEmptyStack,记录当前不为空的stack的下标;还一个是availableStack,记录当前未满的stack的下标。在push的时候,只需要找出availableStack中所有下标的最小值,插入对应的stack即可,如果availableStack为空,新增一个stack,插入stack_list,同时更新availableStack和nonEmptyStack的状态;pop操作则是找出nonEmptyStack中下标的最大值,对其对应的stack做pop操作,而popAsStack的操作就更简单,可以直接用下标访问stack_list。需要注意的是,每次对stack有任何操作,都要同步更新availableStack和nonEmptyStack。因为是求availableStack和nonEmptyStack的最大或者最小值,只需要保证availableStack和nonEmptyStack中的元素有序即可,更新availableStack和nonEmptyStack则可以用二分查找法。

代码如下:

class DinnerPlates(object):

    def __init__(self, capacity):
"""
:type capacity: int
"""
self.stack_list = []
self.availableStack = []
self.capacity = capacity
self.nonEmptyStack = [] def push(self, val):
"""
:type val: int
:rtype: None
"""
if len(self.availableStack) == 0:
inx = len(self.stack_list)
#self.availableStack.append(len(self.stack_list))
self.stack_list.append([val])
if len(self.stack_list[inx]) < self.capacity:
self.availableStack.append(inx)
else:
inx = self.availableStack[0]
self.stack_list[inx].append(val)
if len(self.stack_list[inx]) >= self.capacity:
self.availableStack.pop(0)
import bisect
b_inx = bisect.bisect_left(self.nonEmptyStack,inx)
if b_inx == -1 or b_inx == len(self.nonEmptyStack) or self.nonEmptyStack[b_inx] != inx:
bisect.insort_left(self.nonEmptyStack,inx) def pop(self):
"""
:rtype: int
"""
if len(self.nonEmptyStack) == 0:
return -1
inx = self.nonEmptyStack[-1]
v = self.stack_list[inx].pop(-1)
if len(self.stack_list[inx]) == 0:
self.nonEmptyStack.pop(-1)
return v def popAtStack(self, index):
"""
:type index: int
:rtype: int
"""
import bisect
b_inx = bisect.bisect_left(self.nonEmptyStack, index)
if b_inx == -1 or b_inx == len(self.nonEmptyStack) or self.nonEmptyStack[b_inx] != index:
return -1
v = self.stack_list[index].pop(-1)
if len(self.stack_list[index]) == 0:
del self.nonEmptyStack[b_inx] b_inx = bisect.bisect_left(self.availableStack, index)
if b_inx == -1 or b_inx == len(self.availableStack) or self.availableStack[b_inx] != index:
bisect.insort_left(self.availableStack,index) return v

【leetcode】1172. Dinner Plate Stacks的更多相关文章

  1. 【LeetCode】设计题 design(共38题)

    链接:https://leetcode.com/tag/design/ [146]LRU Cache [155]Min Stack [170]Two Sum III - Data structure ...

  2. 【LeetCode】Minimum Depth of Binary Tree 二叉树的最小深度 java

    [LeetCode]Minimum Depth of Binary Tree Given a binary tree, find its minimum depth. The minimum dept ...

  3. 【Leetcode】Pascal&#39;s Triangle II

    Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3, Return [1,3 ...

  4. 53. Maximum Subarray【leetcode】

    53. Maximum Subarray[leetcode] Find the contiguous subarray within an array (containing at least one ...

  5. 27. Remove Element【leetcode】

    27. Remove Element[leetcode] Given an array and a value, remove all instances of that value in place ...

  6. 【刷题】【LeetCode】007-整数反转-easy

    [刷题][LeetCode]总 用动画的形式呈现解LeetCode题目的思路 参考链接-空 007-整数反转 方法: 弹出和推入数字 & 溢出前进行检查 思路: 我们可以一次构建反转整数的一位 ...

  7. 【刷题】【LeetCode】000-十大经典排序算法

    [刷题][LeetCode]总 用动画的形式呈现解LeetCode题目的思路 参考链接 000-十大经典排序算法

  8. 【leetcode】893. Groups of Special-Equivalent Strings

    Algorithm [leetcode]893. Groups of Special-Equivalent Strings https://leetcode.com/problems/groups-o ...

  9. 【leetcode】657. Robot Return to Origin

    Algorithm [leetcode]657. Robot Return to Origin https://leetcode.com/problems/robot-return-to-origin ...

随机推荐

  1. cocos2dx[3.2](7) 核心类Director/Scene/Layer/Sprite

    [核心类] 导演Director.场景Scene.布景层Layer.精灵Sprite的概念请移步: cocos2dx基础篇(2) 第一个程序 导演控制场景,场景控制图层,图层控制精灵,精灵控制动作. ...

  2. Python学习之协程

    8.8 协程 ​ 我们都知道线程间的任务切换是由操作系统来控制的,而协程的出现,就是为了减少操作系统的开销,由协程来自己控制任务的切换 ​ 协程本质上就是线程.既然能够切换任务,所以线程有两个最基本的 ...

  3. 【Deep Learning Nanodegree Foundation笔记】第 9 课:Model Evaluation and Validation

    In this lesson, you'll learn some of the basics of training models. You'll learn the power of testin ...

  4. vue-loader介绍和单页组件介绍

    $ \es6\sing-file>  npm install vue-loader@14.1.1 -D vue-template-compiler@2.5.17 -D npm install v ...

  5. Android 开源项目及库汇总(2)

    Android 开源项目及库汇总(2) ListenToCode 2.7 2018.10.10 15:43 字数 8527 阅读 1001评论 0喜欢 29 地图 百度地图– Android百度地图 ...

  6. C++ 内联函数 inline关键字

    inline 关键字主要功能是为了 代替掉 宏代码片段. 在C++中使用关键字inline关键字声明内联函数. inline int fun(int a,int b) { return a < ...

  7. 作业调度框架Quartz.NET-现学现用-01-快速入门 - 简书

    原文:作业调度框架Quartz.NET-现学现用-01-快速入门 - 简书 前言 你需要应用执行一个任务吗?这个任务每天或每周星期二晚上11:30,或许仅仅每个月的最后一天执行.一个自动执行而无须干预 ...

  8. 深入理解java虚拟机(4)类加载的过程

    类加载的过程 ------------------------------------------------------- 0.如下图所示JVM类加载机制分为5个部分:加载.验证.准备.解析.初始化 ...

  9. join 与 countdownlatch 的区别 扩展 栅栏 CyclicBarrier

    我们先看一个 小例子 , 使用 join 与CountDownSlatch 都可以完成 当1,2线程 完全结束后 3 线程 start 对比我们就能够知道 CountDownSlatch 比 JOIN ...

  10. redis常见问题和解决方案

    转载:https://www.cnblogs.com/aspirant/p/6820262.html [原创]那些年用过的Redis集群架构(含面试解析) redis常见问题和解决方案 持久化.主从问 ...