LeetCode - 随机集合最长的多类别子序列

Posted SpikeKing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode - 随机集合最长的多类别子序列相关的知识,希望对你有一定的参考价值。

380. O(1) 时间插入、删除和获取随机元素

参考: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 - 随机集合最长的多类别子序列的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode刷题 最长递增子序列

LeetCode(LCSி)最长公共子序列&变形应用

力扣LeetCode-300. 最长递增子序列-题解

力扣LeetCode-300. 最长递增子序列-题解

LeetCode 300. 最长递增子序列

leetcode300. 最长递增子序列