• [LeetCode周赛复盘] 第 310 场周赛20220911


    一、本周周赛总结

    • 排名还在掉,先截图吧。
    • T2不仔细wa了一发,很难受。
    • T4从来没想过LIS还能用线段树优化,后来想想确实是没错,反正大概是上网找了个类似题抄了思路赶紧写的线段树。
    • T3又是堆,最近堆出现的好多。
      在这里插入图片描述

    二、 [Easy] 6176. 出现最频繁的偶数元素

    链接: 6176. 出现最频繁的偶数元素

    1. 题目描述

    在这里插入图片描述

    2. 思路分析

    • 直接计数偶数,然后遍历即可。
    • 要注意如果没有偶数ans应该是-1,但是ans又要取小的,因此先定义成10**6最后发现没变就改成-1.

    3. 代码实现

    class Solution:
        def mostFrequentEven(self, nums: List[int]) -> int:
            cnt = Counter(n for n in nums if (n&1) == 0)
            ans = 10**6
            for k,v in cnt.items():
                if v > cnt[ans]:
                    ans = k
                elif v == cnt[ans]:
                    ans = min(ans,k)
            if ans == 10**6:
                ans = -1
            return ans
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    三、[Medium] 6177. 子字符串的最优划分

    链接: 6177. 子字符串的最优划分

    1. 题目描述

    在这里插入图片描述

    2. 思路分析

    定级Medium。

    • 定义一个计数器,记录每一段中字符出现次数,当发现字符出现2次时,重新起段。
    • 最后数一共多少段即可。
    • 这里wa了一次,因为不起段时忘记计数了。
    • 由于这里最多一次,其实用set更快。

    3. 代码实现

    class Solution:
        def partitionString(self, s: str) -> int:
            n = len(s)
            ans = 1
            cnt = Counter()
            cnt[s[0]] = 1
            for r in range(1,n):
                # print(s[r],cnt)
                if s[r] in cnt:
                    ans += 1
                    cnt = Counter(s[r:r+1])
                else:
                    cnt[s[r]] += 1
            return ans    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    四、[Medium] 6178. 将区间分为最少组数

    链接: 6178. 将区间分为最少组数

    1. 题目描述

    在这里插入图片描述

    2. 思路分析

    定级Medium。

    • 又是堆。
    • 相当于安排会议室,[l,r]是会议开始结束时间,有空闲就安排一个空闲的;如果没有空闲会议室就盖一个新的会议室(/doge)。
    • 把会议按开始时间排序,因为先开始的要优先安排会议室。
    • 用小顶堆来维护每个会议室最后一个会议的结束时间(也就是能空闲出来的时间)。
    • 如果堆顶(最早空出来的时间)的会议室能满足当前会议,则安排,把这个会议室时间更新成当前会议的结束时间。
    • 否则新盖一个会议室(push)。

    3. 代码实现

    class Solution:
        def minGroups(self, intervals: List[List[int]]) -> int:
            n = len(intervals)
            intervals.sort(key=lambda x :x[0])
            
            h = []
            
            for l,r in intervals:
                if h and h[0]<l:
                    heapq.heapreplace(h,r)
                else:
                    heapq.heappush(h,r)
            return len(h)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    五、[Hard] 6206. 最长递增子序列 II

    链接: 6206. 最长递增子序列 II

    1. 题目描述

    在这里插入图片描述

    2. 思路分析

    定级Hard

    • 看了眼数据结构,朴素dp的N方做法肯定过不了。
    • 试了下单调二分优化的nlgn做法,wa了。
    • 最后还是回到朴素DP的优化,先看朴素解法:
    • 令f[i]为以第i个数位结尾的LIS长度(这里LIS指带限制的LIS,即相差不超过K,下边不再赘述)。
    • 显然f[i] = max{f[j]|j
    • 这样的做法是O(n^2)的。
    • 我们发现,j的限制条件其实是指i前边比a[i]所有小的数,且这个数的范围是[a[i]-k,a[i]-1]。
    • 那么我们可以用线段树来维护这个区间所有数字f的最大值。
    • 这样每次操作的时间复杂度优化到了lgn,总体复杂度O(nlgn)就可以过了。

    3. 代码实现

    class IntervalTree:
        def __init__(self, size,nums=None):
            self.size = size
            self.nums = nums
            self.interval_tree = [0]*(size*4)
    
        def update_point(self,p,l,r,index,val):        
            if index < l or r < index:
                return 
            interval_tree = self.interval_tree
            interval_tree[p] =max(interval_tree[p],val)
            if l == r:
                return
            mid = (l+r)//2
            if index <= mid:
                self.update_point(p*2,l,mid,index,val)
            else:
                self.update_point(p*2+1,mid+1,r,index,val)
        
        def query(self,p,l,r,x,y):
            """
            查找x,y区间的最大值        """        
            
            if y < l or r < x:
                return 0
            if x<=l and r<=y:
                return self.interval_tree[p]
            
            mid = (l+r)//2
            s = 0
            if x <= mid:
                s = max(s,self.query(p*2,l,mid,x,y))
            if mid < y:
                s = max(s,self.query(p*2+1,mid+1,r,x,y))
            return s
    
        
    class Solution:
        def lengthOfLIS(self, nums: List[int], k: int) -> int:
            n = len(nums)
            mx = max(nums)
            tree = IntervalTree(mx)
            ans = 0
            for i in range(n):
                v = nums[i]
                l = max(0,v-k)
                r = max(0,v-1)
                ret = tree.query(1,1,mx,l,r)+1
                tree.update_point(1,1,mx,v,ret)
                ans = max(ans,ret)
    
            return ans
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    六、参考链接

  • 相关阅读:
    主流压力测试工具推荐
    springBoot框架简介入门教程(快速学习版)
    准备了 185 万养老金
    设计模式——装饰器模式
    Mac环境部署单机版Hbase及使用JavaAPI对Hbase增删改查
    代码随想录第50天 | 84.柱状图中最大的矩形
    解决方案:反弹shell之后没法通过上下键调出历史命令
    redis GEO使用及基本原理——实现对经纬度的操作
    BSV 上的 PLONK
    混合云中 DevOps 的最佳实践
  • 原文地址:https://blog.csdn.net/liuliangcan/article/details/126803849