Queue
队列,先进先出; deque,双向队列
队列是线性结构,First in First out policy.
enque
deque
Interface
backed by list
class Queue(object):
def __init__(self):
self._items = []
def __len__(self): #O(1)
return len(self._items)
def enqueue(self, item): #O(1)
self._items.append(item)
def dequeue(self): #O(n)
if self.empty():
return None
item = self._item[0]
self._items.pop(0) #等价于del self._items[0] 注意pop如果不指定是弹出最后一个
return item
def empty(self):
return len(self._items)==0
def front(self):
if self.empty():
return None
return self._item[0] backed by singly linkedlist
Double Ended Queue: deque
两端都可以放拿元素,双端队列。如果把它当queue来用,只关注几个函数
append()
appendleft()
pop()
popleft()
右边append, 左边pop;左边append,右边pop
经典问题 Sliding Window
一般可以用1 array或者2pointers 特点是随着窗口的增加,窗口内元素使得窗口的某种性质单调变化,eg. 长度、非负数组的元素总和。
如果不满足单调性,比如 有正有负的array,需要用其他方法,比如prefix sum。
类似的题目分成以下几种:
满足某一要求的max window size
满足某一要求的min window size
满足某一要求的固定size的window有多少个
一个window,使其内值得和/积 最大/最小/小于k/大于k
at most, at least, consecutive, longest subarray等关键词转化成以上某种
Average
给一个window size,一串数,算出sliding window的平均值
Minimum Size Subarray Sum
Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead.
Example:
Input: s = 7, nums = [2,3,1,2,4,3]
Output: 2
Explanation: the subarray [4,3] has the minimal length under the problem constraint.
Max
给一个window size,一串字母,算出无重复字母sliding window的最大长度
思路:LR指针,以每个元素结尾的substring的最长长度存成一个list,输出这个list的最大值。
已经存在的字母可以存成一个hash(dictionary),只要频率大于1就左移左指针,否则左指针不动,右指针右移,list记录的数字是r-l+1
优化:如果只需要求一个max,那就用一个maxL变量维护最大值就行,不用维护整个数组。
Max Consecutive Ones
给一串1、0,如果最多只能翻一次0变1,求最长的数列长度。
Find All Anagrams in a String
Given a string s and a non-empty string p, find all the start indices of p's anagrams in s.
Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20, 100.
The order of output does not matter.
Example 1:
Input:
s: "cbaebabacd" p: "abc"
Output:
[0, 6]
Subarray Product Less Than K
Your are given an array of positive integers nums.
Count and print the number of (contiguous) subarrays where the product of all the elements in the subarray is less than k.
Example 1:
Input: nums = [10, 5, 2, 6], k = 100
Output: 8
Explanation:
The 8 subarrays that have product less than 100 are: [10], [5], [2], [6], [10, 5], [5, 2], [2, 6], [5, 2, 6]. Note that [10, 5, 2] is not included as the product of 100 is not strictly less than k.
Subarray Sum Equals K (all positives)
Subarray Sum Equals K (general)
Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k.
Example 1:
Input: nums = [1,1,1], k = 2
Output: 2
The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].
Longest Substring contains at most k distinct characters
Brute Force:
在一个string里有O( )个substring,每个substring里需要O(n)来比较distinct chars。所以O( ) 也就是S[i:j] 0<=i<=j<=n-1
优化
如果说在两个for循环执行的过程中 for i in range (len(s)): for j in range (i:len(s)): 在s[:t]时就找到了k distinct chars的subarray,s[:t+1]时找到了k+1 distinct chars的subarray,那
j便不用继续t+2,t+3...
i=1时不用看j在[1:t]里的,可以直接跳到t 知道subarray S[i=1...j]里面的元素超过k个了再停下
所以,2pointers,fast移动到里面包含k+1为止,slow移动到k为止。
Follow up: 如果是stream data怎么办
在dict里不存count,而是存每次看到这个字符的位置,这样就可以handle流数据的情况,因为每一次移动start指针的时候,可以直接一步到位移动到当前k+1的这个字符的上一次出现的位置的最小位置+1.
Tree Level Order Traversal (BFS)
Implement a queue with Max API
Implement a queue with Min API
应用
在工作中,data pipeline也会使用sliding window来存值,就像是在做down sampling,就可以存一个统计意义上更小的数据集。

3. System Design、OO Design
Queue
假设有屏幕的width=3, height=2, food的位置([1,2], [0,1]),蛇的位置,实现snake object。
如果要设计一个data structure来表示“🐍”,那就需要update蛇头和蛇尾的坐标。那么deque就可以支持头尾的取放。在尾部取元素是O(1)的操作,在头部加元素也是O(1)的操作。不过如果想要判断头部接下来要在的位置是否会撞上身体,那么brute-force的复杂度是O(n)。如果想在这里优化,引入一个set或者dictionary。
到现在,🐍的身体有两个表现形式,数据结构的组合:一个是set,一个是deque。在更新时,两者都需要更新。
Last updated