Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -75,32 +75,224 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3700-3799/3770.La

<!-- solution:start -->

### 方法一
### 方法一:预处理 + 二分查找

我们可以预处理出所有小于等于 $5 \times 10^5$ 的质数列表,然后计算从 2 开始的连续质数和,并将这些和中是质数的数存储在一个数组中 $s$ 中。

对于每个查询,我们只需要在数组 $s$ 中使用二分查找找到小于等于 $n$ 的最大值即可。

时间复杂度方面,预处理质数的时间复杂度为 $O(M \log \log M)$,每次查询的时间复杂度为 $(\log k)$,其中 $M$ 是预处理的上限,而 $k$ 是数组 $s$ 的长度,本题中 $k \leq 40$。

<!-- tabs:start -->

#### 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<Integer> PRIMES = new ArrayList<>();
private static final List<Integer> 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<bool> IS_PRIME(MX + 1, true);
static vector<int> PRIMES;
static vector<int> 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];
}
```

<!-- tabs:end -->
Expand Down
Loading
Loading