Sorted Containers 是Apache2许可的Sorted Collections库,用纯Python编写,并且速度与C扩展一样快。在需要排序的集合类型之前,Python的标准库非常有用。
顾名思义,就是使用SortedList, SortedDict, SortedSet创建的列表,字典,集合会自动按照字典序排列。大多数情况下,创建时候直接调用Sroted Containers,能使代码更加简洁,高效。当然也可以自己手动维护一个排序列表/字典/集合。
from sortedcontainers import SortedList
s1 = SortedList(['e', 'a', 'c', 'd', 'b'])
s1
Out[127]: SortedList(['a', 'b', 'c', 'd', 'e'])
s1.add('c')
s1
Out[130]: SortedList(['a', 'b', 'c', 'c', 'd', 'e'])
from sortedcontainers import SortedDict
sd = SortedDict({'c': 3, 'a': 1, 'b': 2})
sd
Out[132]: SortedDict({'a': 1, 'b': 2, 'c': 3})
from sortedcontainers import SortedSet
ss = SortedSet('abracadabra')
ss
Out[134]: SortedSet(['a', 'b', 'c', 'd', 'r'])
刷了几道leetcode的算法题,其中用了这个库创建的列表,集合啥的,能通过大批量的超时测试任务。否则,调用min, max函数啥的验证测试会报timeout。
下面两道题,都是要维护一个排序的数据结构,第一道自己用二分排序算法实现的。第二道是调用的sortedcontainers实现的。
都是常规的题目,难点就是返回系统中最小下标的实现。这个问题一般我们会考虑用把所有出现的数字建立字典,然后每个数字出现的下标建立为一个有序数组。调用find函数时候,直接返回有序数组的第0个index即可。
我最开始没有把出现的数字的坐标建立为有序数组,最后find时候,是返回min(index_list),结果超时了。
后来参考别人的代码,建立index数组时候,都直接调用了sortedcontainers库里面的SortedList函数,基于摆脱python库函数的依赖,自己写了二分排序算法来维护index数组为有序数组,完美通过了。
def binarySort(value,arr):
left=0
right=len(arr)
while(left<right-1):
middle=(left+right)//2
if arr[middle]<value:
left=middle
else:
right=middle
if arr[left]<value:
arr.insert(left+1,value)
else:
arr.insert(left,value)
return arr
class NumberContainers:
def __init__(self):
self.val={}
self.d = {}
def change(self, index: int, number: int) -> None:
if index in self.val:
self.d[self.val[index]].remove(index)
self.val[index]=number
if number not in self.d or self.d[number]==[]:
self.d[number] = [index]
else:
self.d[number]=binarySort(index,self.d[number])
def find(self, number: int) -> int:
if number in self.d and self.d[number]:
return self.d[number][0]
else:
return -1
# Your NumberContainers object will be instantiated and called as such:
# obj = NumberContainers()
# obj.change(index,number)
# param_2 = obj.find(number)
这道题关键就是要创建或者维护一个关于某个烹饪方法,foods排分的有序字典和集合。否则如果是无序的排分,如果调用highestRate函数时候,实时的求解,不管你实时求解算法写的多优美,我测试了,timeout是必然。
参考了很多python写法,都是调用了sortedcontainers库的函数。
from sortedcontainers import SortedSet
class FoodRatings:
def __init__(self, foods: List[str], cuisines: List[str], ratings: List[int]):
self.sortRating=defaultdict(SortedSet)
self.f2rc={}
for f,c,r in zip(foods,cuisines,ratings):
self.f2rc[f]=(r,c)
self.sortRating[c].add((-r,f))
def changeRating(self, food: str, newRating: int) -> None:
old_r,c=self.f2rc[food]
self.sortRating[c].remove((-old_r,food))
self.sortRating[c].add((-newRating,food))
self.f2rc[food]=(newRating,c)
def highestRated(self, cuisine: str) -> str:
return self.sortRating[cuisine][0][1]
# Your FoodRatings object will be instantiated and called as such:
# obj = FoodRatings(foods, cuisines, ratings)
# obj.changeRating(food,newRating)
# param_2 = obj.highestRated(cuisine)