[LeetCode周赛复盘] 第 359 场周赛20230820

[LeetCode周赛复盘] 第 359 场周赛20230820

    • 一、本周周赛总结
    • 2828. 判别首字母缩略词
      • 1. 题目描述
      • 2. 思路分析
      • 3. 代码实现
    • 2829. k-avoiding 数组的最小总和
      • 1. 题目描述
      • 2. 思路分析
      • 3. 代码实现
    • 2830. 销售利润最大化
      • 1. 题目描述
      • 2. 思路分析
      • 3. 代码实现
    • 2831. 找出最长等值子数组
      • 1. 题目描述
      • 2. 思路分析
      • 3. 代码实现
    • 参考链接

一、本周周赛总结

  • T1 模拟。
  • T2 数学贪心。
  • T3 dp。
  • T4 分组+滑窗。

[LeetCode周赛复盘] 第 359 场周赛20230820_第1张图片

2828. 判别首字母缩略词

2828. 判别首字母缩略词

1. 题目描述

[LeetCode周赛复盘] 第 359 场周赛20230820_第2张图片

2. 思路分析

按题意模拟即可。

3. 代码实现

class Solution:
    def isAcronym(self, words: List[str], s: str) -> bool:
        return s == ''.join(w[0] for w in words)

2829. k-avoiding 数组的最小总和

2829. k-avoiding 数组的最小总和

1. 题目描述

[LeetCode周赛复盘] 第 359 场周赛20230820_第3张图片

2. 思路分析

贪心

  • 1~k-1中,选了1就不能选k-1;选了2就不能选k-2…
  • 因此可以选1~k//2
  • 剩余的从k开始向上选。

  • 可以模拟,也可以等差数列求和公式。

3. 代码实现

class Solution:
    def minimumSum(self, n: int, k: int) -> int:
        ans = 0
        p = min(n,k//2)
        ans += (1+p)*p//2
        
        ans += (k+k+n-p-1)*(n-p)//2
        return ans

2830. 销售利润最大化

2830. 销售利润最大化

1. 题目描述

[LeetCode周赛复盘] 第 359 场周赛20230820_第4张图片

2. 思路分析

看到值域范围,考虑用值域当下标dp。
令f[i]表示从0~i的房屋的销售最大值。

  • 枚举offers[i]=a,b,c, 只要知道f[a-1]则可以转移到f[b],f[b]=f[a-1]+b。
  • 如何知道f[a-1]呢,显然它是一个前缀最大值,那么其实可以用线段树等区间最大值的数据结构。
  • 这题还可以递推,用p记录当前a之前的最大值,那么可以把offers按左端点排序,记一下即可,然后双指针递推。

3. 代码实现

class Solution:
    def maximizeTheProfit(self, n: int, offers: List[List[int]]) -> int:
        f = [0]*n
        j = p = 0
        offers.sort()
        for a,b,c in offers:
            while j < a:
                p = max(p,f[j])
                j += 1
            f[b] = max(f[b],p+c)
        return max(f[j:])

2831. 找出最长等值子数组

2831. 找出最长等值子数组

1. 题目描述

[LeetCode周赛复盘] 第 359 场周赛20230820_第5张图片

2. 思路分析

  • 由于只能删除k个数,保留的数不能变,那么按值分组,记录下标。
  • 对每个组,看删除k个的窗口内,最多有几个下标。
  • 那么变长滑窗思路就出现了。
  • 枚举每个位置为窗口右边界,如果窗口内需要删除的数字超过k个,那么缩左窗。

3. 代码实现

class Solution:
    def longestEqualSubarray(self, nums: List[int], k: int) -> int:
        n = len(nums)
        g = [[] for _ in range(n+1)]
        for i,v in enumerate(nums):
            g[v].append(i)
        ans = 1 
        for a in g:
            q = deque()
            for v in a:
                q.append(v)
                while q[-1]-q[0]+1 - len(q) > k:
                    q.popleft()
                ans = max(ans,len(q))
        return ans         

参考链接

你可能感兴趣的:(力扣周赛复盘,leetcode,算法,职场和发展)