题目

2614. 对角线上的质数

给你一个下标从 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:

  1. 输入:nums = [[1,2,3],[5,6,7],[9,10,11]]
  2. 输出:11
  3. 解释:数字 1369 11 是所有 "位于至少一条对角线上" 的数字。由于 11 是最大的质数,故返回 11

示例 2:

  1. 输入:nums = [[1,2,3],[5,17,7],[9,11,10]]
  2. 输出:17
  3. 解释:数字 13910 17 是所有满足"位于至少一条对角线上"的数字。由于 17 是最大的质数,故返回 17

提示:

  • 1 <= nums.length <= 300
  • nums.length == numsi.length
  • 1 <= nums[i][j] <= 4*106

思路

​ 本题没什么弯弯绕绕,直接模拟即可。由于在提示中限制了nums.length == numsi.length,2条对角线都是完整的,不需要额外考虑边界:

  • 第1条对角线nums[i][i]
  • 第2条对角线nums[i][n-1-i]

判断质数

​ 对于1个正整数n,如何判断它是不是质数呢?

​ 可以先假设n是合数,那么n必然可以分解成n = x * yx <= y(仅为说明问题,如果 x > y,那么可以交换 x 和 y 来满足 x <= y),显然 x <= sqrt(n)。所以,可以遍历[2, sqrt(n)],如果n能整除其中某个数,就一定是合数。

​ 还有一个额外的注意点是:1既不是质数,也不是合数,需要单独额外判断。

代码

  1. public int diagonalPrime(int[][] nums) {
  2. int ans = 0;
  3. int n = nums.length;
  4. for (int i = 0; i < n; i++) {
  5. if (nums[i][i] > ans && isPrime(nums[i][i])) {
  6. ans = nums[i][i];
  7. }
  8. if (nums[i][n-1-i] > ans && isPrime(nums[i][n-1-i])) {
  9. ans = nums[i][n-1-i];
  10. }
  11. }
  12. return ans;
  13. }
  14. private boolean isPrime(int n) {
  15. if (n == 1) {
  16. return false;
  17. }
  18. for (int i = 2; i <= Math.sqrt(n); i++) {
  19. if (n % i == 0) {
  20. return false;
  21. }
  22. }
  23. return true;
  24. }

​ 这里还有1个小优化:由于isPrime方法需要遍历[2, sqrt(n)]这个范围,相对于nums[i][i] > ans这个判断是比较耗时的,所以我们在写if条件的时候,可以把isPrime方法写在后面,这样如果前面不满足就会短路掉,加快处理的速度。

耗时

预处理

​ 考虑到提示中给出的数的范围[1, 4 * 10^6],这个范围不是很大,在判断质数这一步,我们可以先预处理,求出范围内所有的质数,这样就不用每次调用isPrime方法判断了。这里用到的方法是打表求质数,打表的方式可以简单理解为isPrime方法的逆向:我们不直接从n出发,而是从因子出发,如果n = x * y,n 可以看作是 x 的 y 被,我们把范围内所有的满足 x 的 y 倍的数,都标记成合数,那么剩余的,就都是质数了。同样的,这里也需要对1这个既不是质数,也不是合数的特殊值,进行额外判断。

​ 预处理的优点是,我们保存预处理的结果后,后续的质数判断这一步会变快,当然也付出了存储空间和预处理时间的代价。如果我们的二维数组很大,需要判断是否是质数的次数很大,这个预处理的消耗就会比较值得;如果二维数组很小,且数值的理论范围很大,实际范围比较小,就得不偿失了。

代码

  1. private static final boolean[] isPrimeArr = getPrimeArr(4000000);
  2. public int diagonalPrime(int[][] nums) {
  3. int ans = 0;
  4. int n = nums.length;
  5. for (int i = 0; i < n; i++) {
  6. if (nums[i][i] > ans && isPrimeArr[nums[i][i]]) {
  7. ans = nums[i][i];
  8. }
  9. if (nums[i][n-1-i] > ans && isPrimeArr[nums[i][n-i-1]]) {
  10. ans = nums[i][n-1-i];
  11. }
  12. }
  13. return ans;
  14. }
  15. private static boolean[] getPrimeArr(int n) {
  16. boolean[] isPrimeArr = new boolean[n + 1];
  17. Arrays.fill(isPrimeArr, true);
  18. isPrimeArr[1] = false;
  19. for (int i = 2; i <= Math.sqrt(n); i++) {
  20. for (int j = i + i; j <= n; j += i) {
  21. isPrimeArr[j] = false;
  22. }
  23. }
  24. return isPrimeArr;
  25. }

耗时

leetcode每日一题:对角线上的质数的更多相关文章

  1. 【JavaScript】Leetcode每日一题-在D天内送包裹的能力

    [JavaScript]Leetcode每日一题-在D天内送包裹的能力 [题目描述] 传送带上的包裹必须在 D 天内从一个港口运送到另一个港口. 传送带上的第 i 个包裹的重量为 weights[i] ...

  2. 【JavaScript】Leetcode每日一题-青蛙过河

    [JavaScript]Leetcode每日一题-青蛙过河 [题目描述] 一只青蛙想要过河. 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有). 青蛙可以跳上石子 ...

  3. 【JavaScript】Leetcode每日一题-矩形区域不超过K的最大值和

    [JavaScript]Leetcode每日一题-矩形区域不超过K的最大值和 [题目描述] 给你一个 m x n 的矩阵 matrix 和一个整数 k ,找出并返回矩阵内部矩形区域的不超过 k 的最大 ...

  4. 【JavaScript】【KMP】Leetcode每日一题-实现strStr()

    [JavaScript]Leetcode每日一题-实现strStr() [题目描述] 实现 strStr() 函数. 给你两个字符串 haystack 和 needle ,请你在 haystack 字 ...

  5. [LeetCode每日一题]153.寻找旋转排序数组中的最小值

    [LeetCode每日一题]153.寻找旋转排序数组中的最小值 问题 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组.例如,原数组 nums = [0,1, ...

  6. [LeetCode每日一题]81. 搜索旋转排序数组 II

    [LeetCode每日一题]81. 搜索旋转排序数组 II 问题 已知存在一个按非降序排列的整数数组 nums ,数组中的值不必互不相同. 在传递给函数之前,nums 在预先未知的某个下标 k(0 & ...

  7. 【python】Leetcode每日一题-存在重复元素3

    [python]Leetcode每日一题-存在重复元素3 [题目描述] 给你一个整数数组 nums 和两个整数 k 和 t .请你判断是否存在 两个不同下标 i 和 j,使得 abs(nums[i] ...

  8. 【python】Leetcode每日一题-扰乱字符串

    [python]Leetcode每日一题-扰乱字符串 [题目描述] 使用下面描述的算法可以扰乱字符串 s 得到字符串 t : 如果字符串的长度为 1 ,算法停止 如果字符串的长度 > 1 ,执行 ...

  9. 【python】Leetcode每日一题-搜索排序数组2

    [python]Leetcode每日一题-搜索排序数组2 [题目描述] 已知存在一个按非降序排列的整数数组 nums ,数组中的值不必互不相同. 在传递给函数之前,nums 在预先未知的某个下标 k( ...

  10. 【python】Leetcode每日一题-二叉搜索迭代器

    [python]Leetcode每日一题-二叉搜索迭代器 [题目描述] 实现一个二叉搜索树迭代器类BSTIterator ,表示一个按中序遍历二叉搜索树(BST)的迭代器: BSTIterator(T ...

随机推荐

  1. 我的c语言笔记

    1. 进制转换 二进制.八进制和十六进制向十进制转换都非常容易,就是"按权相加".如:1010.1101 = 1×23 + 0×22 + 1×21 + 0×20 + 1×2-1 + ...

  2. 后端开发之chrome开发者模式-copy

    1. 场景描述 java开发前后端分离模式越来越流行,后端人员可以直接使用swagger进行接口调试(前后端分离之Swagger2),但是调试的时候,需要设置入参,假如该模块不是软件老王开发的,接别人 ...

  3. langchain-知识库问答

    本地接入 百川 langchain调用 参考:https://github.com/datawhalechina/self-llm/blob/master/BaiChuan/03-Baichuan2- ...

  4. Docker与联合文件系统

    1. 联合文件系统 概念 UnionFS(联合文件系统)是一种分层,轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次次的提交来一层一层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(u ...

  5. ABC237

    ABC237 F 题目大意 求长度为 \(n\) 且最长上升子序列长度恰好为 \(3\) 的序列 \(a\) 的个数(\(1 \leq a_i \leq m\)). 解题思路 不难判断这道题是一道线性 ...

  6. Apex pg walkthrough Intermediate

    nmap扫描 ┌──(root㉿kali)-[~] └─# nmap -p- -A 192.168.157.145 Starting Nmap 7.94SVN ( https://nmap.org ) ...

  7. Android平台从上到下,无需ROOT/解锁/刷机,应用级拦截框架的最后一环,SVC系统调用拦截。

    Android平台从上到下,无需ROOT/解锁/刷机,应用级拦截框架的最后一环 -- SVC系统调用拦截. ☞ Github: https://www.github.com/iofomo/abyss ...

  8. 如何在WPS和Word/Excel中直接使用DeepSeek功能

    以下是将DeepSeek功能集成到WPS中的详细步骤,无需本地部署模型,直接通过官网连接使用:1. 下载并安装OfficeAI插件 (1)访问OfficeAI插件下载地址:https://www.of ...

  9. RocketMQ实战—7.生产集群部署和生产参数

    大纲 1.RocketMQ生产集群部署和生产参数分析 2.RocketMQ生产集群10wTPS压测 3.RocketMQ生产级故障案例 1.RocketMQ生产集群部署和生产参数分析 (1)服务器数量 ...

  10. 局域网 yum仓库

    有时候在局域网环境中,每台机器上挂载本地镜像充当yum仓库太麻烦. 可以选择局域网一台服务器生成yum仓库,局域网其他服务器通过http协议访问这台服务器的yum仓库. 一.准备 两台虚拟机,其中 A ...