2327: Number-of-People-Aware-of-a-Secret
Medium
table of contents
attempt 1
My first solution was really stupid.
I initially treated the problem like a sliding window with
two halves. The first half are people that discovered
the secret delay
days ago and are able to
share the secret. The second half are people that
recently discovered the secret and are NOT able to
share the secret.
My algorithm uses a circular array to reduce space complexity, and iterates over the people who can share the secret to calculate how many new people learn it each day.
Exemplar table below:
DAY||1|2|3|4|4|5|6|7|8|
---|-------------------
||0 0|0 1|
| 0|0 0|1 0|
| 0 0|0 1|0 1|
| 0 0 0|1 0|1 1|
| 0 0 0 1|0 1|1 1| | 0 0 0 1 0|1 1|1 2|
code
class Solution {
public:
int peopleAwareOfSecret(int n, int delay, int forget) {
int start = 1;
<long long> days(forget+1, 0);
vectorint size = days.size();
[forget-1] = 1;
days
for (int i = 0; i < n-1; ++i) {
long long sum = 0;
int index = start;
for (int j = 0; j < forget - delay; ++j) {
= (sum + days[index]) % MOD;
sum = (index + 1) % size;
index }
= (index + delay - 1) % size;
index [index] = sum;
days
= (start + 1) % size;
start }
long long ans = 0;
= (size + start - 1) % size;
start for (int i = 0; i < forget; ++i) {
= (ans + days[start]) % MOD;
ans = (start + 1) % size;
start }
return ans;
}
private:
int MOD = 1e9+7;
};
complexity
attempt 2
My second attempt makes a lot more sense. Now, we have a
dp
array instead, and we let it keep track of how many
people learn about the secret on a given day.
Initially, on day 1
, exactly one person knows the secret
so dp[1] = 1
.
<long long> dp (n+1, 0);
vector[1] = 1; dp
Then we maintain a share
variable to keep track of the
number of people sharing the secret on a given day.
int share = 0;
Now, on each day, we update the share
variable:
- we check
dp[max(i - delay, 0)]
and add it toshare
since these people are learning about the secret - we check
dp[max(i - forget, 0)]
and subtract it fromshare
since these people are forgetting about the secret
for (int i = 2; i <= n; ++i) {
[i] = share = (share + dp[max(i - delay, 0)] - dp[max(i - forget, 0)] + MOD) % MOD;
dp}
Afterwards, we can simply go back, iterate through the last
forget
days and sum up all the values to get the
ans
.
int ans = 0;
for (int i = n - forget + 1; i <= n; ++i) {
= (ans + dp[i]) % MOD;
ans }
return ans;
code
class Solution {
public:
int peopleAwareOfSecret(int n, int delay, int forget) {
<long long> dp (n+1, 0);
vector[1] = 1;
dpint share = 0;
for (int i = 2; i <= n; ++i) {
[i] = share = (share + dp[max(i - delay, 0)] - dp[max(i - forget, 0)] + MOD) % MOD;
dp}
int ans = 0;
for (int i = n - forget + 1; i <= n; ++i) {
= (ans + dp[i]) % MOD;
ans }
return ans;
}
private:
const int MOD = 1e9+7;
};