Easy
题目描述
给你一个下标从 0 开始的二维整数数组 nums 。
返回位于 nums 至少一条 对角线 上的最大质数。如果所有对角线上都不存在质数,返回 0 。
注意:
- 如果某个整数大于
1,且除了1和自身之外没有其他正整数因子,那么该整数是一个 质数 。 - 如果存在某个整数
i,使得nums[i][i] = val或者nums[i][nums.length - i - 1] = val,那么整数val位于nums的一条对角线上。
在上面的图中,一条对角线是 [1,5,9] ,另一条对角线是 [3,5,7] 。
示例 1:
输入:nums = [[1,2,3],[5,6,7],[9,10,11]]
输出:11
解释:数字 1、3、6、9 和 11 是位于至少一条对角线上的所有数字。由于 11 是最大的质数,所以返回 11 。
示例 2:
输入:nums = [[1,2,3],[5,17,7],[9,11,10]]
输出:17
解释:数字 1、3、9、10 和 17 都位于至少一条对角线上。17 是最大的质数,所以返回 17 。
提示:
1 <= nums.length <= 300nums.length == nums[i].length1 <= nums[i][j] <= 4 * 10^6
解题思路
这道题要求我们找到矩阵两条对角线上的最大质数。
解题思路:
提取对角线元素:矩阵有两条对角线
- 主对角线:从左上到右下,坐标为
(i, i) - 副对角线:从右上到左下,坐标为
(i, n-1-i)
- 主对角线:从左上到右下,坐标为
质数判断:对每个对角线元素判断是否为质数
- 质数必须大于1
- 只需检查到
√n即可,如果在此范围内没有因子,则为质数
找最大值:遍历所有对角线元素,记录最大的质数
算法步骤:
- 遍历矩阵的对角线位置
- 对每个对角线元素调用质数判断函数
- 维护当前找到的最大质数
- 返回结果(如果没有找到质数则返回0)
优化点:
- 使用集合去重,避免重复检查中心元素(当矩阵大小为奇数时,两条对角线会在中心相交)
- 质数判断使用 O(√n) 算法
代码实现
class Solution {
public:
bool isPrime(int n) {
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
for (int i = 5; i * i <= n; i += 6) {
if (n % i == 0 || n % (i + 2) == 0) {
return false;
}
}
return true;
}
int diagonalPrime(vector<vector<int>>& nums) {
int n = nums.size();
unordered_set<int> diagonalElements;
// 收集对角线元素
for (int i = 0; i < n; i++) {
diagonalElements.insert(nums[i][i]); // 主对角线
diagonalElements.insert(nums[i][n - 1 - i]); // 副对角线
}
int maxPrime = 0;
for (int num : diagonalElements) {
if (isPrime(num)) {
maxPrime = max(maxPrime, num);
}
}
return maxPrime;
}
};
class Solution:
def diagonalPrime(self, nums: List[List[int]]) -> int:
def is_prime(n):
if n <= 1:
return False
if n <= 3:
return True
if n % 2 == 0 or n % 3 == 0:
return False
i = 5
while i * i <= n:
if n % i == 0 or n % (i + 2) == 0:
return False
i += 6
return True
n = len(nums)
diagonal_elements = set()
# 收集对角线元素
for i in range(n):
diagonal_elements.add(nums[i][i]) # 主对角线
diagonal_elements.add(nums[i][n - 1 - i]) # 副对角线
max_prime = 0
for num in diagonal_elements:
if is_prime(num):
max_prime = max(max_prime, num)
return max_prime
public class Solution {
private bool IsPrime(int n) {
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
for (int i = 5; i * i <= n; i += 6) {
if (n % i == 0 || n % (i + 2) == 0) {
return false;
}
}
return true;
}
public int DiagonalPrime(int[][] nums) {
int n = nums.Length;
HashSet<int> diagonalElements = new HashSet<int>();
// 收集对角线元素
for (int i = 0; i < n; i++) {
diagonalElements.Add(nums[i][i]); // 主对角线
diagonalElements.Add(nums[i][n - 1 - i]); // 副对角线
}
int maxPrime = 0;
foreach (int num in diagonalElements) {
if (IsPrime(num)) {
maxPrime = Math.Max(maxPrime, num);
}
}
return maxPrime;
}
}
var diagonalPrime = function(nums) {
function isPrime(n) {
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 === 0 || n % 3 === 0) return false;
for (let i = 5; i * i <= n; i += 6) {
if (n % i === 0 || n % (i + 2) === 0) return false;
}
return true;
}
let maxPrime = 0;
let n = nums.length;
for (let i = 0; i < n; i++) {
if (isPrime(nums[i][i])) {
maxPrime = Math.max(maxPrime, nums[i][i]);
}
if (isPrime(nums[i][n - 1 - i])) {
maxPrime = Math.max(maxPrime, nums[i][n - 1 - i]);
}
}
return maxPrime;
};
复杂度分析
| 复杂度类型 | 值 | 说明 |
|---|---|---|
| 时间复杂度 | O(n + k√m) | n为矩阵大小,k为不同对角线元素个数(最多2n),m为最大元素值 |
| 空间复杂度 | O(n) | 存储对角线元素的哈希集合 |