[英雄星球七月集训LeetCode解题日报] 第16日 队列

本文介绍了如何使用O(n)时间复杂度解决LeetCode第2327题——知道秘密的人数。通过刷表法和差分数组优化,将原本的O(n^2)算法改进,详细阐述了思路和代码实现。同时,提及了此题与斐波那契兔子问题的关联及之前周赛的解题复盘。
摘要由CSDN通过智能技术生成

日报

  • 今天只有一题

题目

一、2327. 知道秘密的人数

链接: 2327. 知道秘密的人数

1. 题目描述

在这里插入图片描述

2. 思路分析
这题其实是斐波那契兔子的变种。

周赛时用的*O(n2)*的线性DP,思考起来比较复杂,具体可以参加我之前的[LeetCode周赛复盘] 第 300 场周赛20220703

  • 今天写一下*O(n)*的做法。
  • 定义f[i]为第i天新知道秘密的人的人数,那么转移可以通过刷表法转移。
  • 通常我们做dp都是针对dp[i],看它能从哪个子状态(如dp[i-1]…dp[j],j<i)转移而来,叫填表法;这里刷表法指的是,处理dp[i]时,看dp[i]能对哪个dp[k]产生贡献,去更新dp[k]的值。
  • 刷表法的题目之前刚好做过一道: 871. 最低加油次数,当然这题可以贪心+优先队列做。
  • 返回这题,刷表其实非常简单了,对于第i天新知道秘密的人数,他们会在第i+delay天开始产生新的人,一直到i+forget天结束(这里注意不要越界)。
  • 最后一段会产生一个如果这帮人产生新人的时间越界了,且他们没遗忘,那他们要累计到答案里,用cnt_b储存(cnt_b代表知道秘密但不能分享的人);
  • 这个算法依然是*O(n2)*的,我们发现内层循环有一个区间加的运算,因此可以差分数组优化。
    在这里插入图片描述
3. 代码实现
MOD = 10**9+7
class Solution:
    def peopleAwareOfSecret(self, n: int, delay: int, forget: int) -> int:        
        diff = [0] * n  # 用差分数组储存 第i天知道秘密且能分享的人
        cnt_b = 0
        diff[0] = 1
        diff[1] = -1
        f = 0
        
        for i,d in enumerate(diff):
            f = (f+d)%MOD
            if i+delay>=n:
                cnt_b += f
            else:
                diff[i+delay] += f 
                if i+forget<n:
                    diff[i+forget] -= f 
        return (f + cnt_b)%MOD

参考链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值