From a57a9f4310adc60100f5daf07cb222de11c4607c Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Mon, 8 Dec 2025 07:40:47 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.3770 --- .../README.md | 200 +++++++++++++++++- .../README_EN.md | 200 +++++++++++++++++- .../Solution.cpp | 40 ++++ .../Solution.go | 43 ++++ .../Solution.java | 43 ++++ .../Solution.py | 23 ++ .../Solution.ts | 36 ++++ 7 files changed, 577 insertions(+), 8 deletions(-) create mode 100644 solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.cpp create mode 100644 solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.go create mode 100644 solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.java create mode 100644 solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.py create mode 100644 solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.ts diff --git a/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/README.md b/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/README.md index 1263ca1c62f03..995f9749c4573 100644 --- a/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/README.md +++ b/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/README.md @@ -75,32 +75,224 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3700-3799/3770.La -### 方法一 +### 方法一:预处理 + 二分查找 + +我们可以预处理出所有小于等于 $5 \times 10^5$ 的质数列表,然后计算从 2 开始的连续质数和,并将这些和中是质数的数存储在一个数组中 $s$ 中。 + +对于每个查询,我们只需要在数组 $s$ 中使用二分查找找到小于等于 $n$ 的最大值即可。 + +时间复杂度方面,预处理质数的时间复杂度为 $O(M \log \log M)$,每次查询的时间复杂度为 $(\log k)$,其中 $M$ 是预处理的上限,而 $k$ 是数组 $s$ 的长度,本题中 $k \leq 40$。 #### Python3 ```python - +mx = 500000 +is_prime = [True] * (mx + 1) +is_prime[0] = is_prime[1] = False +primes = [] +for i in range(2, mx + 1): + if is_prime[i]: + primes.append(i) + for j in range(i * i, mx + 1, i): + is_prime[j] = False +s = [0] +t = 0 +for x in primes: + t += x + if t > mx: + break + if is_prime[t]: + s.append(t) + + +class Solution: + def largestPrime(self, n: int) -> int: + i = bisect_right(s, n) - 1 + return s[i] ``` #### Java ```java - +class Solution { + private static final int MX = 500000; + private static final boolean[] IS_PRIME = new boolean[MX + 1]; + private static final List PRIMES = new ArrayList<>(); + private static final List S = new ArrayList<>(); + + static { + Arrays.fill(IS_PRIME, true); + IS_PRIME[0] = false; + IS_PRIME[1] = false; + + for (int i = 2; i <= MX; i++) { + if (IS_PRIME[i]) { + PRIMES.add(i); + if ((long) i * i <= MX) { + for (int j = i * i; j <= MX; j += i) { + IS_PRIME[j] = false; + } + } + } + } + + S.add(0); + int t = 0; + for (int x : PRIMES) { + t += x; + if (t > MX) { + break; + } + if (IS_PRIME[t]) { + S.add(t); + } + } + } + + public int largestPrime(int n) { + int i = Collections.binarySearch(S, n + 1); + if (i < 0) { + i = ~i; + } + return S.get(i - 1); + } +} ``` #### C++ ```cpp - +static const int MX = 500000; +static vector IS_PRIME(MX + 1, true); +static vector PRIMES; +static vector S; + +auto init = [] { + IS_PRIME[0] = false; + IS_PRIME[1] = false; + + for (int i = 2; i <= MX; i++) { + if (IS_PRIME[i]) { + PRIMES.push_back(i); + if (1LL * i * i <= MX) { + for (int j = i * i; j <= MX; j += i) { + IS_PRIME[j] = false; + } + } + } + } + + S.push_back(0); + int t = 0; + for (int x : PRIMES) { + t += x; + if (t > MX) break; + if (IS_PRIME[t]) { + S.push_back(t); + } + } + + return 0; +}(); + +class Solution { +public: + int largestPrime(int n) { + auto it = upper_bound(S.begin(), S.end(), n); + return *(it - 1); + } +}; ``` #### Go ```go +const MX = 500000 + +var ( + isPrime = make([]bool, MX+1) + primes []int + S []int +) + +func init() { + for i := range isPrime { + isPrime[i] = true + } + isPrime[0] = false + isPrime[1] = false + + for i := 2; i <= MX; i++ { + if isPrime[i] { + primes = append(primes, i) + if i*i <= MX { + for j := i * i; j <= MX; j += i { + isPrime[j] = false + } + } + } + } + + S = append(S, 0) + t := 0 + for _, x := range primes { + t += x + if t > MX { + break + } + if isPrime[t] { + S = append(S, t) + } + } +} + +func largestPrime(n int) int { + i := sort.SearchInts(S, n+1) + return S[i-1] +} +``` +#### TypeScript + +```ts +const MX = 500000; + +const isPrime: boolean[] = Array(MX + 1).fill(true); +isPrime[0] = false; +isPrime[1] = false; + +const primes: number[] = []; +const s: number[] = []; + +(function init() { + for (let i = 2; i <= MX; i++) { + if (isPrime[i]) { + primes.push(i); + if (i * i <= MX) { + for (let j = i * i; j <= MX; j += i) { + isPrime[j] = false; + } + } + } + } + + s.push(0); + let t = 0; + for (const x of primes) { + t += x; + if (t > MX) break; + if (isPrime[t]) { + s.push(t); + } + } +})(); + +function largestPrime(n: number): number { + const i = _.sortedIndex(s, n + 1) - 1; + return s[i]; +} ``` diff --git a/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/README_EN.md b/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/README_EN.md index eb93efafd1b4b..90b7c22595e66 100644 --- a/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/README_EN.md +++ b/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/README_EN.md @@ -70,32 +70,224 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3700-3799/3770.La -### Solution 1 +### Solution 1: Preprocessing + Binary Search + +We can preprocess a list of all prime numbers less than or equal to $5 \times 10^5$, then calculate the consecutive prime sums starting from 2, and store those sums that are prime numbers in an array $s$. + +For each query, we simply need to use binary search in array $s$ to find the maximum value less than or equal to $n$. + +In terms of time complexity, preprocessing the primes takes $O(M \log \log M)$ time, and each query takes $O(\log k)$ time, where $M$ is the upper limit of preprocessing, and $k$ is the length of array $s$. In this problem, $k \leq 40$. #### Python3 ```python - +mx = 500000 +is_prime = [True] * (mx + 1) +is_prime[0] = is_prime[1] = False +primes = [] +for i in range(2, mx + 1): + if is_prime[i]: + primes.append(i) + for j in range(i * i, mx + 1, i): + is_prime[j] = False +s = [0] +t = 0 +for x in primes: + t += x + if t > mx: + break + if is_prime[t]: + s.append(t) + + +class Solution: + def largestPrime(self, n: int) -> int: + i = bisect_right(s, n) - 1 + return s[i] ``` #### Java ```java - +class Solution { + private static final int MX = 500000; + private static final boolean[] IS_PRIME = new boolean[MX + 1]; + private static final List PRIMES = new ArrayList<>(); + private static final List S = new ArrayList<>(); + + static { + Arrays.fill(IS_PRIME, true); + IS_PRIME[0] = false; + IS_PRIME[1] = false; + + for (int i = 2; i <= MX; i++) { + if (IS_PRIME[i]) { + PRIMES.add(i); + if ((long) i * i <= MX) { + for (int j = i * i; j <= MX; j += i) { + IS_PRIME[j] = false; + } + } + } + } + + S.add(0); + int t = 0; + for (int x : PRIMES) { + t += x; + if (t > MX) { + break; + } + if (IS_PRIME[t]) { + S.add(t); + } + } + } + + public int largestPrime(int n) { + int i = Collections.binarySearch(S, n + 1); + if (i < 0) { + i = ~i; + } + return S.get(i - 1); + } +} ``` #### C++ ```cpp - +static const int MX = 500000; +static vector IS_PRIME(MX + 1, true); +static vector PRIMES; +static vector S; + +auto init = [] { + IS_PRIME[0] = false; + IS_PRIME[1] = false; + + for (int i = 2; i <= MX; i++) { + if (IS_PRIME[i]) { + PRIMES.push_back(i); + if (1LL * i * i <= MX) { + for (int j = i * i; j <= MX; j += i) { + IS_PRIME[j] = false; + } + } + } + } + + S.push_back(0); + int t = 0; + for (int x : PRIMES) { + t += x; + if (t > MX) break; + if (IS_PRIME[t]) { + S.push_back(t); + } + } + + return 0; +}(); + +class Solution { +public: + int largestPrime(int n) { + auto it = upper_bound(S.begin(), S.end(), n); + return *(it - 1); + } +}; ``` #### Go ```go +const MX = 500000 + +var ( + isPrime = make([]bool, MX+1) + primes []int + S []int +) + +func init() { + for i := range isPrime { + isPrime[i] = true + } + isPrime[0] = false + isPrime[1] = false + + for i := 2; i <= MX; i++ { + if isPrime[i] { + primes = append(primes, i) + if i*i <= MX { + for j := i * i; j <= MX; j += i { + isPrime[j] = false + } + } + } + } + + S = append(S, 0) + t := 0 + for _, x := range primes { + t += x + if t > MX { + break + } + if isPrime[t] { + S = append(S, t) + } + } +} + +func largestPrime(n int) int { + i := sort.SearchInts(S, n+1) + return S[i-1] +} +``` +#### TypeScript + +```ts +const MX = 500000; + +const isPrime: boolean[] = Array(MX + 1).fill(true); +isPrime[0] = false; +isPrime[1] = false; + +const primes: number[] = []; +const s: number[] = []; + +(function init() { + for (let i = 2; i <= MX; i++) { + if (isPrime[i]) { + primes.push(i); + if (i * i <= MX) { + for (let j = i * i; j <= MX; j += i) { + isPrime[j] = false; + } + } + } + } + + s.push(0); + let t = 0; + for (const x of primes) { + t += x; + if (t > MX) break; + if (isPrime[t]) { + s.push(t); + } + } +})(); + +function largestPrime(n: number): number { + const i = _.sortedIndex(s, n + 1) - 1; + return s[i]; +} ``` diff --git a/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.cpp b/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.cpp new file mode 100644 index 0000000000000..d33beb9a1133e --- /dev/null +++ b/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.cpp @@ -0,0 +1,40 @@ +static const int MX = 500000; +static vector IS_PRIME(MX + 1, true); +static vector PRIMES; +static vector S; + +auto init = [] { + IS_PRIME[0] = false; + IS_PRIME[1] = false; + + for (int i = 2; i <= MX; i++) { + if (IS_PRIME[i]) { + PRIMES.push_back(i); + if (1LL * i * i <= MX) { + for (int j = i * i; j <= MX; j += i) { + IS_PRIME[j] = false; + } + } + } + } + + S.push_back(0); + int t = 0; + for (int x : PRIMES) { + t += x; + if (t > MX) break; + if (IS_PRIME[t]) { + S.push_back(t); + } + } + + return 0; +}(); + +class Solution { +public: + int largestPrime(int n) { + auto it = upper_bound(S.begin(), S.end(), n); + return *(it - 1); + } +}; diff --git a/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.go b/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.go new file mode 100644 index 0000000000000..2092352f939cd --- /dev/null +++ b/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.go @@ -0,0 +1,43 @@ +const MX = 500000 + +var ( + isPrime = make([]bool, MX+1) + primes []int + S []int +) + +func init() { + for i := range isPrime { + isPrime[i] = true + } + isPrime[0] = false + isPrime[1] = false + + for i := 2; i <= MX; i++ { + if isPrime[i] { + primes = append(primes, i) + if i*i <= MX { + for j := i * i; j <= MX; j += i { + isPrime[j] = false + } + } + } + } + + S = append(S, 0) + t := 0 + for _, x := range primes { + t += x + if t > MX { + break + } + if isPrime[t] { + S = append(S, t) + } + } +} + +func largestPrime(n int) int { + i := sort.SearchInts(S, n+1) + return S[i-1] +} diff --git a/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.java b/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.java new file mode 100644 index 0000000000000..d6e35e24c9175 --- /dev/null +++ b/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.java @@ -0,0 +1,43 @@ +class Solution { + private static final int MX = 500000; + private static final boolean[] IS_PRIME = new boolean[MX + 1]; + private static final List PRIMES = new ArrayList<>(); + private static final List S = new ArrayList<>(); + + static { + Arrays.fill(IS_PRIME, true); + IS_PRIME[0] = false; + IS_PRIME[1] = false; + + for (int i = 2; i <= MX; i++) { + if (IS_PRIME[i]) { + PRIMES.add(i); + if ((long) i * i <= MX) { + for (int j = i * i; j <= MX; j += i) { + IS_PRIME[j] = false; + } + } + } + } + + S.add(0); + int t = 0; + for (int x : PRIMES) { + t += x; + if (t > MX) { + break; + } + if (IS_PRIME[t]) { + S.add(t); + } + } + } + + public int largestPrime(int n) { + int i = Collections.binarySearch(S, n + 1); + if (i < 0) { + i = ~i; + } + return S.get(i - 1); + } +} diff --git a/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.py b/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.py new file mode 100644 index 0000000000000..9aba7d3d5108f --- /dev/null +++ b/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.py @@ -0,0 +1,23 @@ +mx = 500000 +is_prime = [True] * (mx + 1) +is_prime[0] = is_prime[1] = False +primes = [] +for i in range(2, mx + 1): + if is_prime[i]: + primes.append(i) + for j in range(i * i, mx + 1, i): + is_prime[j] = False +s = [0] +t = 0 +for x in primes: + t += x + if t > mx: + break + if is_prime[t]: + s.append(t) + + +class Solution: + def largestPrime(self, n: int) -> int: + i = bisect_right(s, n) - 1 + return s[i] diff --git a/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.ts b/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.ts new file mode 100644 index 0000000000000..ad3f582f84457 --- /dev/null +++ b/solution/3700-3799/3770.Largest Prime from Consecutive Prime Sum/Solution.ts @@ -0,0 +1,36 @@ +const MX = 500000; + +const isPrime: boolean[] = Array(MX + 1).fill(true); +isPrime[0] = false; +isPrime[1] = false; + +const primes: number[] = []; +const s: number[] = []; + +(function init() { + for (let i = 2; i <= MX; i++) { + if (isPrime[i]) { + primes.push(i); + if (i * i <= MX) { + for (let j = i * i; j <= MX; j += i) { + isPrime[j] = false; + } + } + } + } + + s.push(0); + let t = 0; + for (const x of primes) { + t += x; + if (t > MX) break; + if (isPrime[t]) { + s.push(t); + } + } +})(); + +function largestPrime(n: number): number { + const i = _.sortedIndex(s, n + 1) - 1; + return s[i]; +}