当前位置: 首页 > news >正文

每日算法-250523

每日算法学习记录 - 250523

2748. 美丽下标对的数目

题目

题目截图 - 2748. 美丽下标对的数目

思路

数组

解题过程

题目要求当 i < j 时,nums[i] 的第一个数字要和 nums[j] 的最后一个数字互质。
我们知道,nums[i] 的第一个数字必然落在 1-9 之间。因此,我们可以用一个大小为 10 的数组 map 来记录:当遍历到 nums[j] 时,在 j 之前(即 0j-1 的索引)出现的数字中,其首位数字分别是 1-9 的各有几个。

遍历 nums 数组中的每个元素 x (代表 nums[j]):

  1. 获取 x 的最后一位数字 cur = x % 10
  2. 遍历 map 数组的索引 k 从 1 到 9(k 代表之前某个 nums[i] 的首位数字)。
  3. 如果 map[k] != 0 (即之前存在首位为 k 的数字) 并且 gcd(k, cur) == 1 (首位 k 与当前数字 x 的末位 cur 互质),则将 map[k] 的值累加到结果 ret 中。这意味着之前所有首位为 k 的数字都与当前数字 x 构成了美丽下标对。
  4. 获取当前数字 x 的首位数字 first = getFirstNum(x)
  5. map[first] 的计数加 1,为后续的数字作准备。

复杂度

  • 时间复杂度: O ( N ⋅ log ⁡ M ) O(N \cdot \log M) O(NlogM)
    其中 N N N 是数组 nums 的长度。对于 nums 中的每个元素,我们会执行一个常数次数(最多9次)的 gcd 运算。gcd(a, b) 的时间复杂度是 O ( log ⁡ ( min ⁡ ( a , b ) ) ) O(\log(\min(a,b))) O(log(min(a,b))),但在这里 ab 都是个位数,所以 gcd 操作可以近似看作 O ( 1 ) O(1) O(1)getFirstNum(x) 操作的时间复杂度是 O ( log ⁡ 10 x ) O(\log_{10} x) O(log10x),即 O ( log ⁡ M ) O(\log M) O(logM),其中 M M Mnums 中元素的最大值。因此,总体时间复杂度为 O ( N ⋅ ( constant + log ⁡ M ) ) ≈ O ( N log ⁡ M ) O(N \cdot (\text{constant} + \log M)) \approx O(N \log M) O(N(constant+logM))O(NlogM)
  • 辅助空间复杂度: O ( N ) O(N) O(N)

Code

class Solution {public int countBeautifulPairs(int[] nums) {int ret = 0;int[] map = new int[10]; // map[d] 存储已遍历过的数字中,首位是 d 的数字个数for (int x : nums) {int lastDigitOfX = x % 10;// 遍历所有可能的首位数字 (1-9)for (int firstDigitOfPrev = 1; firstDigitOfPrev < 10; firstDigitOfPrev++) {if (map[firstDigitOfPrev] != 0) { // 如果存在首位是 firstDigitOfPrev 的数字if (gcd(firstDigitOfPrev, lastDigitOfX) == 1) {ret += map[firstDigitOfPrev];}}}int firstDigitOfX = getFirstNum(x);map[firstDigitOfX]++;}return ret;}// 获取数字 x 的最高位private int getFirstNum(int x) {while (x >= 10) {x /= 10;}return x;}private int gcd(int a, int b) {if (b == 0) {return a;}return gcd(b, a % b);}
}

881. 救生艇(复习)

题目

题目截图 - 881. 救生艇

这是第二次写这道题,写的还不错,基本上掌握了,就不再多说了,详细题解见每日算法-250428

代码

class Solution {public int numRescueBoats(int[] people, int limit) {Arrays.sort(people);int ret = 0;int left = 0, right = people.length - 1; while (left <= right) {if (people[right] + people[left] <= limit) {left++;}ret++;right--;}return ret;}
}

20. 有效的括号(复习)

题目

题目截图 - 20. 有效的括号

很久之前的一道题目了,现在再写已经算是掌握了,也不再多说了,详细题解见每日算法-250329

代码

class Solution {public boolean isValid(String s) {Stack<Character> stack = new Stack<>();for (char c : s.toCharArray()) {if (c == '(' || c == '[' || c == '{') {stack.push(c);} else {if (stack.isEmpty()) { // 右括号多于左括号return false;}char topChar = stack.peek();if (c == ')' && topChar != '(') {return false;}if (c == ']' && topChar != '[') {return false;}if (c == '}' && topChar != '{') {return false;}stack.pop(); // 匹配成功,弹出栈顶左括号}}return stack.isEmpty(); // 如果栈为空,说明所有括号都匹配了}
}

http://www.xdnf.cn/news/617041.html

相关文章:

  • 1.2.1+1.2.2计算机硬件的基本组成
  • 通信专业速成solidworks学习记录
  • 有限时间 vs 固定时间 vs 预定时间滑模:稳定性分析与仿真验证方法对比(上)
  • 本地分支git push 报错 fatal: The current branch XXXX has no upstream branch.
  • 负号和连接号的区别?
  • 【C++】20. AVL树的实现
  • Python+requests实现接口自动化测试
  • 机器学习 Day1
  • 【python】局域网内通过python远程重启另一台windows电脑
  • Ntfs!ReadIndexBuffer函数调用Ntfs!NtfsMapStream函数的参数FileOffset为什么是0
  • PPP 流程已经走到启动阶段并且成功进入了 “STAGE_START_PPP
  • Linux PXE批量装机+无人值守技术(自动化装机)
  • [特殊字符] GUNION SDK 接口调用方式说明(静态库 vs 动态库)
  • 树莓派的刷机和登录
  • 常见证书格式区别
  • 矩阵详解:线性代数在AI大模型中的核心支柱
  • win11 24H2 版本,运行.vbs错误:没有文件扩展“.vbs“的脚本引擎
  • 夺命充电何时休?电瓶车入室起火事件频发
  • Linux C/C++编程 —— 线程技术总结
  • 家政维修平台实战09:推送数据到多维表格
  • 得力DE-620K针式打印机打印速度不能调节维修一例
  • AI Engine Kernel and Graph Programming--知识分享6
  • 深度探讨:AI 的全能边界 —— 哪些任务仍超越当前技术范畴?
  • 高校外卖小程序,怎么落地实践?
  • echarts之折线柱状图
  • 【ISP算法精粹】ISP算法管线的预处理算法有哪些?
  • Linux之 SPI 驱动框架- spi-mem 框架
  • 虚拟化工具libvirt日志文件的结构化使用指南
  • Python 脚本执行命令的深度探索:方法、示例与最佳实践
  • 蓝桥杯2025.5.23每日一题-儿童数