class Solution {
public:
vector<int> closestPrimes(int left, int right) {
}
};
2523. 范围内最接近的两个质数
给你两个正整数 left
和 right
,请你找到两个整数 num1
和 num2
,它们满足:
left <= nums1 < nums2 <= right
。nums1
和 nums2
都是 质数 。nums2 - nums1
是满足上述条件的质数对中的 最小值 。请你返回正整数数组 ans = [nums1, nums2]
。如果有多个整数对满足上述条件,请你返回 nums1
最小的质数对。如果不存在符合题意的质数对,请你返回 [-1, -1]
。
如果一个整数大于 1
,且只能被 1
和它自己整除,那么它是一个质数。
示例 1:
输入:left = 10, right = 19 输出:[11,13] 解释:10 到 19 之间的质数为 11 ,13 ,17 和 19 。 质数对的最小差值是 2 ,[11,13] 和 [17,19] 都可以得到最小差值。 由于 11 比 17 小,我们返回第一个质数对。
示例 2:
输入:left = 4, right = 6 输出:[-1,-1] 解释:给定范围内只有一个质数,所以题目条件无法被满足。
提示:
1 <= left <= right <= 106
原站题解
python3 解法, 执行用时: 448 ms, 内存消耗: 25.8 MB, 提交时间: 2023-01-03 11:49:26
MX = 10 ** 6 + 1 primes = [] is_prime = [True] * MX for i in range(2, MX): if is_prime[i]: primes.append(i) for p in primes: if i * p >= MX: break is_prime[i * p] = False if i % p == 0: break primes.extend((MX, MX)) # 保证下面下标不会越界 class Solution: def closestPrimes(self, left: int, right: int) -> List[int]: p = q = -1 i = bisect_left(primes, left) while primes[i + 1] <= right: if p < 0 or primes[i + 1] - primes[i] < q - p: p, q = primes[i], primes[i + 1] i += 1 return [p, q]
java 解法, 执行用时: 28 ms, 内存消耗: 41 MB, 提交时间: 2023-01-03 11:49:09
class Solution { private final static int MX = (int) 1e6; private final static int[] primes = new int[78500]; static { var np = new boolean[MX + 1]; var pi = 0; for (var i = 2; i <= MX; ++i) { if (!np[i]) primes[pi++] = i; for (var j = 0; j < pi; ++j) { var p = primes[j]; if (i * p > MX) break; np[i * p] = true; if (i % p == 0) break; } } primes[pi++] = MX + 1; primes[pi++] = MX + 1; // 保证下面下标不会越界 } public int[] closestPrimes(int left, int right) { int p = -1, q = -1; for (var i = lowerBound(primes, left); primes[i + 1] <= right; ++i) if (p < 0 || primes[i + 1] - primes[i] < q - p) { p = primes[i]; q = primes[i + 1]; } return new int[]{p, q}; } // 见 https://www.bilibili.com/video/BV1AP41137w7/ private int lowerBound(int[] nums, int target) { int left = -1, right = nums.length; // 开区间 (left, right) while (left + 1 < right) { // 区间不为空 // 循环不变量: // nums[left] < target // nums[right] >= target int mid = left + (right - left) / 2; if (nums[mid] < target) left = mid; // 范围缩小到 (mid, right) else right = mid; // 范围缩小到 (left, mid) } return right; } }
golang 解法, 执行用时: 4 ms, 内存消耗: 3.4 MB, 提交时间: 2023-01-03 11:48:45
const mx = 1e6 + 1 var primes = make([]int, 0, 78500) func init() { np := [mx]bool{} for i := 2; i < mx; i++ { if !np[i] { primes = append(primes, i) } for _, p := range primes { if i*p >= mx { break } np[i*p] = true if i%p == 0 { break } } } primes = append(primes, mx, mx) // 保证下面下标不会越界 } func closestPrimes(left, right int) []int { p, q := -1, -1 for i := sort.SearchInts(primes, left); primes[i+1] <= right; i++ { if p < 0 || primes[i+1]-primes[i] < q-p { p, q = primes[i], primes[i+1] } } return []int{p, q} }
golang 解法, 执行用时: 8 ms, 内存消耗: 3.4 MB, 提交时间: 2023-01-03 11:48:30
const mx = 1e6 + 1 var primes = make([]int, 0, 78500) func init() { np := [mx]bool{} for i := 2; i < mx; i++ { if !np[i] { primes = append(primes, i) for j := i * i; j < mx; j += i { np[j] = true } } } primes = append(primes, mx, mx) // 保证下面下标不会越界 } func closestPrimes(left, right int) []int { p, q := -1, -1 for i := sort.SearchInts(primes, left); primes[i+1] <= right; i++ { if p < 0 || primes[i+1]-primes[i] < q-p { p, q = primes[i], primes[i+1] } } return []int{p, q} }
java 解法, 执行用时: 9 ms, 内存消耗: 41 MB, 提交时间: 2023-01-03 11:48:08
class Solution { private final static int MX = (int) 1e6; private final static int[] primes = new int[78500]; static { var np = new boolean[MX + 1]; var pi = 0; for (var i = 2; i <= MX; ++i) if (!np[i]) { primes[pi++] = i; for (var j = i; j <= MX / i; ++j) // 避免溢出的写法 np[i * j] = true; } primes[pi++] = MX + 1; primes[pi++] = MX + 1; // 保证下面下标不会越界 } public int[] closestPrimes(int left, int right) { int p = -1, q = -1; for (var i = lowerBound(primes, left); primes[i + 1] <= right; ++i) if (p < 0 || primes[i + 1] - primes[i] < q - p) { p = primes[i]; q = primes[i + 1]; } return new int[]{p, q}; } // 见 https://www.bilibili.com/video/BV1AP41137w7/ private int lowerBound(int[] nums, int target) { int left = -1, right = nums.length; // 开区间 (left, right) while (left + 1 < right) { // 区间不为空 // 循环不变量: // nums[left] < target // nums[right] >= target int mid = left + (right - left) / 2; if (nums[mid] < target) left = mid; // 范围缩小到 (mid, right) else right = mid; // 范围缩小到 (left, mid) } return right; } }
python3 解法, 执行用时: 372 ms, 内存消耗: 25.7 MB, 提交时间: 2023-01-03 11:47:29
MX = 10 ** 6 + 1 primes = [] is_prime = [True] * MX for i in range(2, MX): if is_prime[i]: primes.append(i) for j in range(i * i, MX, i): is_prime[j] = False primes.extend((MX, MX)) # 保证下面下标不会越界 class Solution: def closestPrimes(self, left: int, right: int) -> List[int]: p = q = -1 i = bisect_left(primes, left) while primes[i + 1] <= right: if p < 0 or primes[i + 1] - primes[i] < q - p: p, q = primes[i], primes[i + 1] i += 1 return [p, q]