[差分数组]2327. 知道秘密的人数

2327. 知道秘密的人数

这个解决方案使用差分数组(Difference Array)高效地处理了区间修改问题,计算第 n天结束时知道秘密的人数。以下是代码的详细解释:

核心思路

  1. 1.​差分数组 diff​:
    • •用于记录每天知道秘密人数的变化量(增量或减量)。
    • •初始化:diff[1] = 1表示第 1 天新增 1 人(初始知道秘密的人),diff[2] = -1是为了在差分数组中标记区间结束(确保前缀和计算正确)。
  2. 2.​变量说明​:
    • know:记录当前第 i天结束时知道秘密的总人数(包括当天新增和之前未忘记的人)。
    • ans:累计最后 forget天内知道秘密的人数(即第 n天结束时未忘记的人)。
  3. 3.​处理逻辑​:
    • 遍历每一天 i(从 1 到 n):

      • 更新 know​:know = (know + diff[i]) % MOD,加上当天的变化量(新增或减少)。

      • 累加答案​:如果 i >= n - forget + 1,说明当前 know中的人在第 n天结束时未忘记,累加到 ans

      • 传播秘密​:当前 know中的人会在 i + delay天分享秘密,导致那天新增 know人,因此更新 diff[i + delay] += know

      • 忘记秘密​:当前 know中的人会在 i + forget天忘记,因此更新 diff[i + forget] -= know

    • 使用 min(i + delay, n + 1)min(i + forget, n + 1)确保不越界。

关键点解析

  • 差分数组的作用​:将区间修改(如多人同时分享或忘记)转换为两个端点的修改,时间复杂度从 O(n) 降为 O(1)。

  • know的含义​:表示第 i天结束时知道秘密的总人数,包括当天新增和之前未忘记的人。

  • 传播与忘记的时机​:

    • 分享:第 i天的人会在 i + delay天分享,导致那天新增 know人。

    • 忘记:第 i天的人会在 i + forget天忘记,导致那天减少 know人。

  • 答案计算​:最后 forget天(i >= n - forget + 1)的 know之和,因为这些人第 n天结束时未忘记。

示例说明

n = 6, delay = 2, forget = 4为例:

  • 第 1 天:know = 1(初始人),传播到第 3 天(diff[3] += 1),忘记在第 5 天(diff[5] -= 1)。

  • 第 2 天:know = 0(无变化)。

  • 第 3 天:know = 1(第 3 天新增),传播到第 5 天(diff[5] += 1),忘记在第 7 天(越界忽略)。

  • 第 4 天:know = 1(第 4 天新增),传播到第 6 天(diff[6] += 1),忘记在第 8 天(越界忽略)。

  • 第 5 天:know = 1(第 5 天新增),传播到第 7 天(越界),忘记在第 9 天(越界)。

  • 第 6 天:know = 2(第 6 天新增),传播和忘记越界。

  • 最后 forget天(第 3 到 6 天):ans = 1 + 1 + 1 + 2 = 5

复杂度

  • 时间复杂度​:O(n),遍历每一天,每次更新差分数组的端点。

  • 空间复杂度​:O(n),差分数组长度 n + 2

代码总结

class Solution:
    def peopleAwareOfSecret(self, n: int, delay: int, forget: int) -> int:
        MOD = 1000000007
        diff = [0] * (n + 2)  # 差分数组,长度 n+2 防越界
        diff[1] = 1  # 第 1 天新增 1 人
        diff[2] = -1  # 差分结束标记
        ans = 0
        know = 0  # 当前知道秘密的总人数
        for i in range(1, n + 1):  # 遍历每一天
            know = (know + diff[i]) % MOD  # 更新当前知道人数
            if i >= n - forget + 1:  # 最后 forget 天内的人未忘记
                ans = (ans + know) % MOD
            # 传播:当前 know 人会在 i+delay 天新增 know 人
            diff[min(i + delay, n + 1)] = (diff[min(i + delay, n + 1)] + know) % MOD
            # 忘记:当前 know 人会在 i+forget 天减少 know 人
            diff[min(i + forget, n + 1)] = (diff[min(i + forget, n + 1)] - know) % MOD
        return ans % MOD

此方案高效利用差分数组处理动态区间修改,适用于大量区间操作的场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值