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

每日算法-250504

每日算法 - 250504

记录今天解决的几道 LeetCode 算法题。


605. 种花问题

题目描述:

在这里插入图片描述

思路

贪心

这道题可以使用贪心策略。核心思想是:当我们遍历花坛时,一旦遇到一个可以种花的位置,就立即种花。因为在一个位置种花不会影响到更左边的位置是否能种花,而尽早种花可能会让右边的位置有更多种花的机会(或者说,不会让右边的情况变得更糟)。所以,局部最优(能种就种)可以导致全局最优(种最多的花)。

解题过程

遍历 flowerbed 数组,检查每个位置 i 是否可以种花。

  1. 位置 i 必须是 0 (没有花)。
  2. 位置 i 的左边必须是 0 (或者 i 是第一个位置)。
  3. 位置 i 的右边必须是 0 (或者 i 是最后一个位置)。

同时满足这三个条件,就可以在位置 i 种一朵花,并将 flowerbed[i] 更新为 1,同时将需要种植的花的数量 k 减一。

为了简化边界判断,可以在原数组两端各补一个 0,但这会增加空间复杂度。另一种方法是在循环中处理边界情况:

  • i = 0 时,只需检查 flowerbed[i]flowerbed[i+1]
  • i = n - 1 时,只需检查 flowerbed[i-1]flowerbed[i]
  • 对于中间位置 0 < i < n - 1,需要检查 flowerbed[i-1], flowerbed[i], 和 flowerbed[i+1]

需要特别处理 n = 1 的情况。如果只有一个位置,能种花的条件是该位置为 0,最多能种 1 朵。

复杂度

  • 时间复杂度: O ( n ) O(n) O(n), 其中 n n nflowerbed 的长度。我们只需要遍历数组一次。
  • 空间复杂度: O ( 1 ) O(1) O(1), 我们只使用了常数级别的额外空间(修改是在原数组上进行的)。

Code

class Solution {public boolean canPlaceFlowers(int[] flowerbed, int k) {int n = flowerbed.length;if (n == 1) {return (flowerbed[0] == 0 ? true : k == 0);}for (int i = 0; i < n && k > 0; i++) {if (flowerbed[i] == 0) {if (i == 0) {if (flowerbed[i + 1] == 0) {flowerbed[i] = 1;k--;}} else if (i == n - 1) {if (flowerbed[i - 1] == 0) {flowerbed[i] = 1;k--;} } else {if (flowerbed[i - 1] == 0 && flowerbed[i + 1] == 0) {flowerbed[i] = 1;k--;}}}}return k == 0;}
}

3111. 覆盖所有点的最少矩形数目

题目描述:

在这里插入图片描述

思路

贪心

由于矩形的高度没有限制,我们只需要关注点的横坐标 x。为了用最少的矩形覆盖所有点,我们应该让每个矩形的宽度 w 尽可能地覆盖更多的点。

解题过程

  1. 将所有点 points 按照横坐标 x 从小到大排序。这使得我们可以线性地处理点。
  2. 初始化所需矩形数量 ret = 1(至少需要一个矩形来覆盖第一个点)。
  3. 维护一个当前矩形能覆盖的最左边的点的索引 left(初始为 0)。
  4. 遍历排序后的点(从第二个点开始,索引为 right)。
  5. 对于每个点 points[right],计算它与当前矩形最左点 points[left] 的横坐标之差 points[right][0] - points[left][0]
  6. 如果这个差值大于 w,说明当前点 points[right] 无法被当前的矩形覆盖。因此,我们需要一个新的矩形来覆盖 points[right] 以及后续的点。此时,增加矩形数量 ret++,并将 points[right] 作为新的矩形的起始点,即更新 left = right
  7. 继续遍历,直到所有点都被检查过。
  8. 最终的 ret 就是所需的最小矩形数量。

复杂度

  • 时间复杂度: O ( N log ⁡ N ) O(N \log N) O(NlogN), 主要是排序所需的时间。遍历过程是 O ( N ) O(N) O(N)
  • 空间复杂度: O ( log ⁡ N ) O(\log N) O(logN) O ( N ) O(N) O(N), 取决于排序算法使用的额外空间。如果忽略排序空间或者排序是原地进行的,可以认为是 O ( 1 ) O(1) O(1)

Code

class Solution {public int minRectanglesToCoverPoints(int[][] points, int w) {Arrays.sort(points, (arr1, arr2) -> Integer.compare(arr1[0], arr2[0]));int ret = 1;for (int left = 0, right = 0; right < points.length; right++) {if (points[right][0] - points[left][0] > w) {ret++;left = right;}}return ret;}
}

2957. 消除相邻近似相等字符

题目描述:

在这里插入图片描述

思路

贪心

我们要最小化修改次数。考虑相邻的两个近似相等字符 s[i-1]s[i]。我们必须修改其中一个。

  • 如果修改 s[i-1],可能会导致 s[i-2] 和修改后的 s[i-1] 近似相等。
  • 如果修改 s[i],它会同时解决 s[i-1]s[i] 之间的问题。并且,修改 s[i] 后,它与 s[i+1] 是否近似相等是后续需要考虑的问题。

贪心策略:从左到右遍历字符串。当发现 s[i]s[i-1] 近似相等时,选择修改 s[i]。因为修改 s[i] 可以确保 s[i-1]s[i] 不再近似相等。修改 s[i] 后,s[i]s[i+1] 之间的关系就与 s[i-1] 无关了。为了确保修改后的 s[i] 不会与 s[i+1] 冲突,并且尽可能少地影响后续决策,一个有效的贪心做法是:修改 s[i] 并跳过对 s[i+1] 的检查。因为我们修改了 s[i],所以 s[i]s[i+1] 肯定不会是需要处理的“原始”近似相等对了。我们只需要统计修改次数,不需要实际执行修改。

解题过程

  1. 将字符串转换为字符数组 s (方便操作,虽然也可以直接用 charAt)。
  2. 初始化修改次数 ret = 0
  3. 从第二个字符开始遍历 (i = 1s.length - 1)。
  4. 检查 s[i]s[i-1] 是否近似相等(Math.abs(s[i] - s[i-1]) <= 1)。
  5. 如果近似相等,说明需要进行一次修改。增加 ret++。因为我们选择修改 s[i],那么无论 s[i] 修改成什么,它都不会再和 s[i-1] 近似相等。同时,为了避免这次修改影响 s[i]s[i+1] 的判断,我们直接跳过下一个字符的检查,即 i++
  6. 如果 s[i]s[i-1] 不近似相等,继续检查下一个位置 i+1
  7. 返回最终的修改次数 ret

复杂度

  • 时间复杂度: O ( n ) O(n) O(n), 其中 n n n 是字符串 word 的长度。我们只需要遍历字符串(或字符数组)一次。
  • 空间复杂度: O ( n ) O(n) O(n) 如果使用了 toCharArray()。如果直接使用 word.charAt(i) 进行遍历,则空间复杂度为 O ( 1 ) O(1) O(1)

Code

class Solution {public int removeAlmostEqualCharacters(String word) {char[] s = word.toCharArray();int ret = 0;for (int i = 1; i < s.length; i++) {if (Math.abs(s[i] - s[i - 1]) <= 1) {ret++;i++;}}return ret;}
}

162. 寻找峰值(复习)

题目描述:

在这里插入图片描述

这是第二次写这道题了,写的还不错,就不再多说了。

详细题解见之前的笔记:每日算法-250414

Code

class Solution {public int findPeakElement(int[] nums) {int left = 0, right = nums.length - 1;while (left <= right) {int mid = left + (right - left) / 2;if (mid != nums.length - 1 && nums[mid] < nums[mid + 1]) {left = mid + 1;} else {right = mid - 1;}}return left;}
}

相关文章:

  • 即梦AI视频3.0模型提示词创作设定
  • 【C++重载操作符与转换】下标操作符
  • n8n工作流自动化平台的实操:生成统计图的两种方式
  • QT数据库实验
  • AVL树(2):
  • 性能优化实践:渲染性能优化
  • Python|Pyppeteer实现自动登录小红书(32)
  • 蓝桥杯15届国赛 合法密码
  • 基于 ESP32 和 GC9D01 0.71寸TFT屏幕的逼真眼睛与写轮眼动态显示
  • 2025年- H26-Lc134- 226. 翻转二叉树(树)---java版
  • 《AI大模型应知应会100篇》第48篇:构建企业级大模型应用的架构设计
  • STM32教程:ADC原理及程序(基于STM32F103C8T6最小系统板标准库开发)*详细教程*
  • 01背包专题4:小A点菜
  • Q_OBJECT宏的作用
  • 深度学习中保存最优模型的实践与探索:以食物图像分类为例
  • 【nlohmann\json.hpp】‘_snprintf‘: is not a member of ‘std‘
  • Uni-app 组件使用
  • Git 远程操作
  • 二叉搜索树的最近祖先(递归遍历)
  • 《工业社会的诞生》章节
  • 巴基斯坦宣布禁止印度船只入港
  • 人民日报今日谈:以青春之我,赴时代之约
  • 河南博物院:警惕非官方网络平台 “买讲解保进馆” 等虚假信息
  • 竞彩湃|拜仁冲冠战役或有冷门,大巴黎留力欧冠半决赛
  • 准80后遵义市自然资源局局长陈清松任怀仁市委副书记、代市长
  • 全国共有共青团员7531.8万名,共青团组织439.7万个