Skip to content

Leetcode 2327. Number of People Aware of a Secret #131

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Woodyiiiiiii opened this issue Jul 3, 2022 · 0 comments
Open

Leetcode 2327. Number of People Aware of a Secret #131

Woodyiiiiiii opened this issue Jul 3, 2022 · 0 comments

Comments

@Woodyiiiiiii
Copy link
Owner

Woodyiiiiiii commented Jul 3, 2022

这道题我一开始想的是尽量分开使用delay和forget两个参数,所以将forget放到最后计算。dp[i]表示第i天刚知道secret的人数。时间复杂度是O(n*2)。

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;
        
    }
}

一位朋友使用O(n)的时间复杂度可以做出。但问题是,因为每个计算过程都要mod,遇到减法时就会出错,比如5-1=4, 5%2-1=0,而最后再用mod使用long类型可能会溢出。所以使用BigInteger可以防止溢出。时间复杂度为O(n)。

dp[i]表示第i天及之前知道secret的人数。所以最后要减去forget secret的人数。

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();
        
    }
}

为了避免上述说的减法取余的情况,加上一个mod即可。其余做法跟上述算法相同。

稍微不同的是,share一开始为0。dp[i]表示的是第i天净知道secret的人数。所以最后要相加。

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;
        
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant