LeetCode - 随机集合最长的多类别子序列
Posted SpikeKing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode - 随机集合最长的多类别子序列相关的知识,希望对你有一定的参考价值。
380. O(1) 时间插入、删除和获取随机元素
随机字典:
- 访问数据O(1),使用数组 + 字典
- 插入时,直接操作数组就是O(1)时间
- 删除时,需要重整数组,需要字典保存末尾的位置,替换删除的数字,也是O(1)时间
- 随机时,直接调用random.choice(list)
import random
class RandomizedSet:
"""
随机字典
访问数据O(1),使用数组 + 字典
插入时,直接操作数组就是O(1)时间;
删除时,需要重整数组,需要字典保存末尾的位置,替换删除的数字,也是O(1)时间
随机,直接调用random.choice(list)
"""
def __init__(self):
self.nums = [] # 存储数据
self.indices = # 记录位置
def insert(self, val: int) -> bool:
if val in self.indices:
return False
self.indices[val] = len(self.nums)
self.nums.append(val)
return True
def remove(self, val: int) -> bool:
if val not in self.indices:
return False
vid = self.indices[val] #返回val的索引
self.nums[vid] = self.nums[-1] # 紧密排列
self.indices[self.nums[vid]] = vid # 同时更新索引
self.nums.pop() # 最后已经替换,可以出栈
self.indices.pop(val) # 删除字典特定值
return True
def getRandom(self) -> int:
return random.choice(self.nums)
904. 水果成篮
参考:904. 水果成篮
输入一个列表nums,每个数值代表一个类别,和最多可选类别k,k表示子序列最多可选的类别数,默认选择2个类别。输出满足所选类别数小于等于k的最长子序列。
实例:
输入:nums = [3,3,3,1,2,1,1,2,3,3,4], k=2
输出:5
解释:可以选择 [1,2,1,1,2] 这个最长子序列。
子序列:
- 滑动窗口解决问题,输出最大的窗口长度
- 当种类数大于n(=2)时,增加窗口左值,缩小窗口,直到某一个类别全部出窗口为止。
- 循环,增大窗口右值,不满足条件,缩小窗口左值
- 时间:O(N),空间O(N)
class Solution:
def totalFruit(self, fruits: List[int]) -> int:
"""
滑动窗口解决问题,输出最大的窗口长度
当种类数大于n(=2)时,增加窗口左值,缩小窗口,直到某一个类别全部出窗口为止。
循环,增大窗口右值,不满足条件,缩小窗口左值
时间:O(N),空间O(N)
"""
res = 0
left = 0
# collections.defaultdict(int) 与 collections.Counter() 相同
count = collections.defaultdict(int)
# 遍历果树
for right, f in enumerate(fruits):
count[f] += 1
while len(count) > 2: # 当种类大于2个的时候,需要出去一个种类
count[fruits[left]] -= 1
if count[fruits[left]] == 0: # 去除种类
count.pop(fruits[left])
left += 1
res = max(res, right - left + 1)
return res
以上是关于LeetCode - 随机集合最长的多类别子序列的主要内容,如果未能解决你的问题,请参考以下文章