@@ -75,32 +75,224 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3700-3799/3770.La
7575
7676<!-- solution:start -->
7777
78- ### 方法一
78+ ### 方法一:预处理 + 二分查找
79+
80+ 我们可以预处理出所有小于等于 $5 \times 10^5$ 的质数列表,然后计算从 2 开始的连续质数和,并将这些和中是质数的数存储在一个数组中 $s$ 中。
81+
82+ 对于每个查询,我们只需要在数组 $s$ 中使用二分查找找到小于等于 $n$ 的最大值即可。
83+
84+ 时间复杂度方面,预处理质数的时间复杂度为 $O(M \log \log M)$,每次查询的时间复杂度为 $(\log k)$,其中 $M$ 是预处理的上限,而 $k$ 是数组 $s$ 的长度,本题中 $k \leq 40$。
7985
8086<!-- tabs:start -->
8187
8288#### Python3
8389
8490``` python
85-
91+ mx = 500000
92+ is_prime = [True ] * (mx + 1 )
93+ is_prime[0 ] = is_prime[1 ] = False
94+ primes = []
95+ for i in range (2 , mx + 1 ):
96+ if is_prime[i]:
97+ primes.append(i)
98+ for j in range (i * i, mx + 1 , i):
99+ is_prime[j] = False
100+ s = [0 ]
101+ t = 0
102+ for x in primes:
103+ t += x
104+ if t > mx:
105+ break
106+ if is_prime[t]:
107+ s.append(t)
108+
109+
110+ class Solution :
111+ def largestPrime (self , n : int ) -> int :
112+ i = bisect_right(s, n) - 1
113+ return s[i]
86114```
87115
88116#### Java
89117
90118``` java
91-
119+ class Solution {
120+ private static final int MX = 500000 ;
121+ private static final boolean [] IS_PRIME = new boolean [MX + 1 ];
122+ private static final List<Integer > PRIMES = new ArrayList<> ();
123+ private static final List<Integer > S = new ArrayList<> ();
124+
125+ static {
126+ Arrays . fill(IS_PRIME , true );
127+ IS_PRIME [0 ] = false ;
128+ IS_PRIME [1 ] = false ;
129+
130+ for (int i = 2 ; i <= MX ; i++ ) {
131+ if (IS_PRIME [i]) {
132+ PRIMES . add(i);
133+ if ((long ) i * i <= MX ) {
134+ for (int j = i * i; j <= MX ; j += i) {
135+ IS_PRIME [j] = false ;
136+ }
137+ }
138+ }
139+ }
140+
141+ S . add(0 );
142+ int t = 0 ;
143+ for (int x : PRIMES ) {
144+ t += x;
145+ if (t > MX ) {
146+ break ;
147+ }
148+ if (IS_PRIME [t]) {
149+ S . add(t);
150+ }
151+ }
152+ }
153+
154+ public int largestPrime (int n ) {
155+ int i = Collections . binarySearch(S , n + 1 );
156+ if (i < 0 ) {
157+ i = ~ i;
158+ }
159+ return S . get(i - 1 );
160+ }
161+ }
92162```
93163
94164#### C++
95165
96166``` cpp
97-
167+ static const int MX = 500000 ;
168+ static vector<bool > IS_PRIME (MX + 1, true);
169+ static vector<int > PRIMES;
170+ static vector<int > S;
171+
172+ auto init = [ ] {
173+ IS_PRIME[ 0] = false;
174+ IS_PRIME[ 1] = false;
175+
176+ for (int i = 2; i <= MX; i++) {
177+ if (IS_PRIME[i]) {
178+ PRIMES.push_back(i);
179+ if (1LL * i * i <= MX) {
180+ for (int j = i * i; j <= MX; j += i) {
181+ IS_PRIME[j] = false;
182+ }
183+ }
184+ }
185+ }
186+
187+ S.push_back(0);
188+ int t = 0;
189+ for (int x : PRIMES) {
190+ t += x;
191+ if (t > MX) break;
192+ if (IS_PRIME[t]) {
193+ S.push_back(t);
194+ }
195+ }
196+
197+ return 0;
198+ }();
199+
200+ class Solution {
201+ public:
202+ int largestPrime(int n) {
203+ auto it = upper_bound(S.begin(), S.end(), n);
204+ return * (it - 1);
205+ }
206+ };
98207```
99208
100209#### Go
101210
102211```go
212+ const MX = 500000
213+
214+ var (
215+ isPrime = make([]bool, MX+1)
216+ primes []int
217+ S []int
218+ )
219+
220+ func init() {
221+ for i := range isPrime {
222+ isPrime[i] = true
223+ }
224+ isPrime[0] = false
225+ isPrime[1] = false
226+
227+ for i := 2; i <= MX; i++ {
228+ if isPrime[i] {
229+ primes = append(primes, i)
230+ if i*i <= MX {
231+ for j := i * i; j <= MX; j += i {
232+ isPrime[j] = false
233+ }
234+ }
235+ }
236+ }
237+
238+ S = append(S, 0)
239+ t := 0
240+ for _, x := range primes {
241+ t += x
242+ if t > MX {
243+ break
244+ }
245+ if isPrime[t] {
246+ S = append(S, t)
247+ }
248+ }
249+ }
250+
251+ func largestPrime(n int) int {
252+ i := sort.SearchInts(S, n+1)
253+ return S[i-1]
254+ }
255+ ```
103256
257+ #### TypeScript
258+
259+ ``` ts
260+ const MX = 500000 ;
261+
262+ const isPrime: boolean [] = Array (MX + 1 ).fill (true );
263+ isPrime [0 ] = false ;
264+ isPrime [1 ] = false ;
265+
266+ const primes: number [] = [];
267+ const s: number [] = [];
268+
269+ (function init() {
270+ for (let i = 2 ; i <= MX ; i ++ ) {
271+ if (isPrime [i ]) {
272+ primes .push (i );
273+ if (i * i <= MX ) {
274+ for (let j = i * i ; j <= MX ; j += i ) {
275+ isPrime [j ] = false ;
276+ }
277+ }
278+ }
279+ }
280+
281+ s .push (0 );
282+ let t = 0 ;
283+ for (const x of primes ) {
284+ t += x ;
285+ if (t > MX ) break ;
286+ if (isPrime [t ]) {
287+ s .push (t );
288+ }
289+ }
290+ })();
291+
292+ function largestPrime(n : number ): number {
293+ const i = _ .sortedIndex (s , n + 1 ) - 1 ;
294+ return s [i ];
295+ }
104296```
105297
106298<!-- tabs:end -->
0 commit comments