You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
class Solution {
public int peopleAwareOfSecret(int n, int delay, int forget) {
long mod = 1000000007;
long[] dp = new long[n + 1];
dp[1] = 1;
for (int i = 1; i < n; ++i) {
for (int j = i + delay; j < i + forget && j <= n; ++j) {
dp[j] = (dp[j] + dp[i]) % mod;
}
}
long res = 0;
for (int i = n; i > n - forget; --i) {
res = (res + dp[i]) % mod;
}
return (int) res;
}
}
import java.math.BigInteger;
class Solution {
public int peopleAwareOfSecret(int n, int delay, int forget) {
BigInteger[] dp = new BigInteger[n + 1];
BigInteger mod = BigInteger.valueOf(1000000007);
dp[0] = BigInteger.valueOf(0);
dp[1] = BigInteger.valueOf(1);
for (int i = 2; i <= n; i++) {
BigInteger sum = BigInteger.valueOf(0);
if (i - delay >= 0) {
sum = sum.add(dp[i - delay]);
}
if (i - forget >= 0) {
sum = sum.subtract(dp[i - forget]);
}
dp[i] = dp[i - 1].add(sum).mod(mod);
}
return dp[n].subtract(dp[n - forget]).mod(mod).intValue();
}
}
class Solution {
public int peopleAwareOfSecret(int n, int delay, int forget) {
long dp[] = new long[n + 1];
long mod = (long)1e9 + 7;
long share = 0;
long res = 0;
dp[1] = 1;
for (int i = 2; i <= n; ++i) {
dp[i] = share = (share + dp[Math.max(i - delay, 0)] - dp[Math.max(i - forget, 0)] + mod) % mod;
}
for (int i = n - forget + 1; i <= n; ++i) {
res = (res + dp[i]) % mod;
}
return (int)res;
}
}
这道题我一开始想的是尽量分开使用delay和forget两个参数,所以将forget放到最后计算。dp[i]表示第i天刚知道secret的人数。时间复杂度是O(n*2)。
一位朋友使用O(n)的时间复杂度可以做出。但问题是,因为每个计算过程都要mod,遇到减法时就会出错,比如5-1=4, 5%2-1=0,而最后再用mod使用long类型可能会溢出。所以使用BigInteger可以防止溢出。时间复杂度为O(n)。
dp[i]表示第i天及之前知道secret的人数。所以最后要减去forget secret的人数。
为了避免上述说的减法取余的情况,加上一个mod即可。其余做法跟上述算法相同。
稍微不同的是,share一开始为0。dp[i]表示的是第i天净知道secret的人数。所以最后要相加。
The text was updated successfully, but these errors were encountered: