【LeetCode周赛】2022上半年题目精选集——数学

文章目录

  • 2183. 统计可以被 K 整除的下标对数目⭐⭐⭐⭐⭐
    • 思路——数论(一个数乘上另一个数x是k的倍数,x最小是多少?)
      • 代码1——统计每个数的因子
      • 代码2——统计k的因子
  • 2245. 转角路径的乘积中最多能有几个尾随零
    • 思路(因子2和5的个数 + 前缀和)⭐⭐⭐⭐⭐
    • 代码
  • 2281. 巫师的总力量和⭐⭐⭐⭐⭐
    • 思路——贡献法(单调栈求左右端点) + 前缀和的前缀和
    • 代码
  • 2310. 个位数字为 K 的整数之和
    • 解法——枚举集合的大小
      • 代码1——自己写的
      • 代码2——力扣官解

https://leetcode.cn/circle/discuss/G0n5iY/

2183. 统计可以被 K 整除的下标对数目⭐⭐⭐⭐⭐

2183. 统计可以被 K 整除的下标对数目
在这里插入图片描述
提示:

1 <= nums.length <= 10^5
1 <= nums[i], k <= 10^5

思路——数论(一个数乘上另一个数x是k的倍数,x最小是多少?)

对于一个固定的数字 nums[j] ,要想和 nums[i] 配对,那么 nums[i] 必须是某个数字 x 的倍数。
那么 x 最小是多少呢? (为了找到所有符合条件的 nums[i] ,我们需要找到最小的 x)

从数论的结论来看, x = k g c d ( n u m s [ j ] , k ) x = \frac{k}{gcd(nums[j], k)} x=gcd(nums[j],k)k,这里 k 就是题目中的 k。
为什么呢?可以从因子的角度去考虑,如果 nums[j] 和 k 有一些公因子,那么可以从 k 中除去这些公因子,这样 x 会变小,那么除去最大公因子是最优的

代码1——统计每个数的因子

我们可以不断枚举 nums[j],在这个过程中记录前面枚举过的 x 的倍数有多少个记为 cnt[x],那么枚举到 nums[j] 的时候就给答案加上多少。

class Solution {final static int mx = 100001;// 记录每个数字的所有因子static List<List<Integer>> divisors = new ArrayList(mx);static {for (int i = 0; i < mx; ++i) divisors.add(new ArrayList());for (int i = 1; i < mx; ++i) {for (int j = i; j < mx; j += i) {// j是i的倍数,所以把i放进j的因子列表里divisors.get(j).add(i);}}}public long countPairs(int[] nums, int k) {long ans = 0;Map<Integer, Integer> cnt = new HashMap();for (int num: nums) {ans += cnt.getOrDefault(k / gcd(num, k), 0);for (int d: divisors.get(num)) {cnt.merge(d, 1, Integer::sum);}}return ans;}public static int gcd(int a, int b) {return b == 0? a: gcd(b, a % b);}
}

代码2——统计k的因子

注意到 x 是 k 的因子,因此可以将代码 1 中统计 num 的因子改为 统计 num 是 k 的哪些因子的倍数,这可以通过 枚举 k 的所有因子 来判断。

class Solution {public long countPairs(int[] nums, int k) {// 统计k的因子List<Integer> divisors = new ArrayList();for (int d = 1; d * d <= k; ++d) {if (k % d == 0) {divisors.add(d);if (d * d < k) divisors.add(k / d);}}long ans = 0;Map<Integer, Integer> cnt = new HashMap();for (int num: nums) {ans += cnt.getOrDefault(k / gcd(num, k), 0);for (int d: divisors) {if (num % d == 0) cnt.merge(d, 1, Integer::sum);}}return ans;}public static int gcd(int a, int b) {return b == 0? a: gcd(b, a % b);}
}

2245. 转角路径的乘积中最多能有几个尾随零

2245. 转角路径的乘积中最多能有几个尾随零

在这里插入图片描述
提示:

m == grid.length
n == grid[i].length
1 <= m, n <= 10^5
1 <= m * n <= 10^5
1 <= grid[i][j] <= 1000

思路(因子2和5的个数 + 前缀和)⭐⭐⭐⭐⭐

在这里插入图片描述
计算出每个数字含有多少个 2 和 多少个 5,最后尾随 0 的个数就是 2 和 5 的数量的最小值。

代码

class Solution {static int[][] c25 = new int[1001][2];static {// 预处理,递推出每个数的因子2和因子5的个数for (int i = 2; i <= 1000; ++i) {if (i % 2 == 0) c25[i][0] = c25[i / 2][0] + 1;if (i % 5 == 0) c25[i][1] = c25[i / 5][1] + 1;}}public int maxTrailingZeros(int[][] grid) {int m = grid.length, n = grid[0].length, ans = 0;int[][][] s = new int[m][n + 1][2];for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {// 每行的因子2或5的前缀和数量s[i][j + 1][0] = s[i][j][0] + c25[grid[i][j]][0];s[i][j + 1][1] = s[i][j][1] + c25[grid[i][j]][1];}}for (int j = 0; j < n; ++j) {       // 枚举每一列// 从上往下,枚举左拐还是右拐for (int i = 0, s2 = 0, s5 = 0; i < m; ++i) {s2 += c25[grid[i][j]][0];s5 += c25[grid[i][j]][1];int left = Math.min(s2 + s[i][j][0], s5 + s[i][j][1]);int right = Math.min(s2 + s[i][n][0] - s[i][j + 1][0], s5 + s[i][n][1] - s[i][j + 1][1]);ans = Math.max(ans, Math.max(left, right));}// 从下往上,枚举左拐还是右拐for (int i = m - 1, s2 = 0, s5 = 0; i >= 0; --i) {s2 += c25[grid[i][j]][0];s5 += c25[grid[i][j]][1];int left = Math.min(s2 + s[i][j][0], s5 + s[i][j][1]);int right = Math.min(s2 + s[i][n][0] - s[i][j + 1][0], s5 + s[i][n][1] - s[i][j + 1][1]);ans = Math.max(ans, Math.max(left, right));}}return ans;}
}

注意学习 递推出每个数的因子2和因子5的个数 的方法。
即:

static int[][] c25 = new int[1001][2];
static {// 预处理,递推出每个数的因子2和因子5的个数for (int i = 2; i <= 1000; ++i) {if (i % 2 == 0) c25[i][0] = c25[i / 2][0] + 1;if (i % 5 == 0) c25[i][1] = c25[i / 5][1] + 1;}
}

2281. 巫师的总力量和⭐⭐⭐⭐⭐

2281. 巫师的总力量和
在这里插入图片描述
提示:

1 <= strength.length <= 105
1 <= strength[i] <= 109

思路——贡献法(单调栈求左右端点) + 前缀和的前缀和

笔者认为本题的主要难点在于 前缀和的前缀和求法。

关于贡献法可见:【算法】贡献法相关题目练习

关于前缀和的前缀和的计算可见:https://leetcode.cn/problems/sum-of-total-strength-of-wizards/solutions/1510399/dan-diao-zhan-qian-zhui-he-de-qian-zhui-d9nki/ 或 下图计算过程。
请添加图片描述
注意这里说的所有子数组指的是所有包括元素 strength[i] 的子数组

代码

class Solution {public int totalStrength(int[] strength) {final int mod = (int)1e9 + 7;int n = strength.length;int[] s = new int[n + 1], ss = new int[n + 2];// 前缀和的前缀和for (int i = 0; i < n; ++i) {s[i + 1] = (s[i] + strength[i]) % mod;  ss[i + 2] = (ss[i + 1] + s[i + 1]) % mod;}int[] left = new int[n], right = new int[n];Arrays.fill(left, -1);Arrays.fill(right, n);Deque<Integer> stk = new ArrayDeque();for (int i = 0; i < n; ++i) {while (!stk.isEmpty() && strength[i] <= strength[stk.peek()]) right[stk.pop()] = i;if (!stk.isEmpty()) left[i] = stk.peek();stk.push(i);}long ans = 0;for (int i = 0; i < n; ++i) {int l = left[i] + 1, r = right[i] - 1;// 前缀和的前缀和推出的公式long tot = ((long)(i - l + 1) * (ss[r + 2] - ss[i + 1]) - (long)(r - i + 1) * (ss[i + 1] - ss[l])) % mod;ans = (ans + tot * strength[i]) % mod;}return (int)(ans + mod) % mod;}
}

2310. 个位数字为 K 的整数之和

2310. 个位数字为 K 的整数之和
在这里插入图片描述
提示:
0 <= num <= 3000
0 <= k <= 9

解法——枚举集合的大小

我们可以知道集合的大小不会超过 10,因为 11 个 个位是 k 的数字相乘,最后的个位数字还是 k ,没有影响。

代码1——自己写的

class Solution {public int minimumNumbers(int num, int k) {if (num == 0) return 0;int n = num % 10, ans = 1;while (ans < 11 && (ans * k % 10 != n)) ++ans;return ans <= 10 && ans * k <= num? ans: -1;}
}

自己写的代码丑陋了一下,因为循环写的不好所以需要对结果加一些额外的判断。

代码2——力扣官解

class Solution {public int minimumNumbers(int num, int k) {if (num == 0) return 0;for (int i = 1; i <= 10; ++i) {if (k * i <= num && (num - k * i) % 10 == 0) return i;}return -1;}
}

官解的答案优雅很多,依次判断 1 ~ 10 是否满足答案,满足就返回,不满足就最后返回 -1。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/19099.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【雕爷学编程】Arduino动手做(138)---64位WS2812点阵屏模块2

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

STM32的MAP文件

1. MAP文件是什么&#xff1f;有什么作用&#xff1f; MAP文件是 MDK编译代码后&#xff0c;产生的集程序、数据及IO空间的一种映射列表文件。简单来说就是包括了&#xff1a;各种.c文件、函数、符号等的地址、大小、引用关系等信息。 作用&#xff1a; 用于分析各.c文件占用…

SpringBoot高频面试题

2023最新版&#xff08;持续更新&#xff09; SpringBoot高频面试题1. SpringBoot的自动配置原理1. SpringBoot的常见注解有哪些&#xff1f; SpringBoot高频面试题 1. SpringBoot的自动配置原理 前置知识 SpringBoot中&#xff0c;在启动类上的SpringBootApplication注解中的…

java.lang.UnsatisfiedLinkError: no opencv_java410 in java.library.path

-Djava.library.pathhome/zwf/eclipse-workspace/DIPS_YTPC/lib/opencv-410/x64/

机器学习总览

机器学习 1.什么是机器学习?2.机器学习的应用3.怎么实现机器学习?1、NumPy库2.Matplotlib库1.什么是机器学习? 机器学习是使计算机像人类一样学习与行动的科学,并通过观察与现实世界交互的形式向计算机提供数据和信息,从而随着时间的推移以自主的方式改善其学习。通过经验…

分布式负载均衡 Ribbon

一、Ribbon简介 是Netfix发布的负载均衡&#xff0c;Eureka一般配合Ribbon进行使用&#xff0c;基于HTTP和TCP的客户端负载均衡工具。 只有负载均衡的能力&#xff0c;不具有发送请求的能力&#xff0c;要配合服务通信组件。 RestTemplate 针对各种类型的 HTTP 请求都提供了相…

zookeeper单机安装

1 检查环境jdk 参考&#xff1a;https://blog.csdn.net/weixin_44098426/article/details/128446376 2 解压安装包 mkdir -p /opt/zookeeper mv /home/wh/software/zk/apache-zookeeper-3.5.7-bin.tar.gz /opt/zookeeper tar -xzvf apache-zookeeper-3.5.7-bin.tar.gz 3 配置…

掌握这些写简历投简历的“黑魔法”,告别简历已读不回!

“哎&#xff0c;我还能找到工作吗&#xff1f;” 这是最近加我微信的好友&#xff0c;问的最多的一句话。 太卷了 最近加我微信的朋友很多&#xff0c;我都很奇怪&#xff0c;最近也没怎么发文章&#xff0c;怎么会有这么多人加我。 大概就是因为太卷了&#xff0c;之前写的…

[工业互联-14]:机器人操作系统ROS与ROS2是如何提升实时性的?

目录 第1章 简介 第2章 历史 第3章 特点 &#xff08;1&#xff09;点对点设计 &#xff08;2&#xff09;不依赖编程语言 &#xff08;3&#xff09;精简与集成 &#xff08;4&#xff09;便于测试 &#xff08;5&#xff09;开源 &#xff08;6&#xff09;强大的库及…

TexSpire-比markdown更为简洁的文本标记语言,用文字即可生成演示效果

文章目录 一、前言二、语言特点三、举例1、文本框2、表格3、折线图4、思维导图 四、相关资料 一、前言 老实说&#xff0c;本人对于ppt的花里胡哨深恶痛绝&#xff0c;特别是每一次汇报&#xff0c;都需要花费我很多时间去找模板&#xff0c;去设计&#xff0c;去美化内容时&a…

Vue3挂载全局方法及组件中如何使用

文章目录 前言一、在mian.ts&#xff08;mian.js&#xff09;中配置全局变量1、如何封装 二、如何调用1.template中调用2.在script标签中如何拿到 前言 在Vue3项目中&#xff0c;需要频繁使用某一个方法。配置到全局感觉会方便很多。 例如&#xff1a;因为很多页面都需要对时…

ASCII码对照表 十六进制的字符对照表

ASCII码对照表&#xff08;包括二进制、十进制十六进制和字符&#xff09; 可以显示 不可以显示