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

每日算法-250425

每日算法打卡 - 2025年4月25日

记录今天完成的几道 LeetCode 算法题,分享解题思路和代码。


2178. 拆分成最多数目的正偶数之和

题目
题目截图 2178

解题思路

贪心算法

解题过程

题目要求我们将一个偶数 finalSum 拆分成尽可能多的 不同 正偶数之和。

为了使拆分出的数字数量最多,我们应该尽可能选择小的偶数。因此,可以采用贪心策略:从最小的正偶数 2 开始,依次尝试添加 4, 6, 8, …,并不断更新剩余的 finalSum

具体步骤如下:

  1. 初始化一个空列表 ret 用于存放结果。
  2. 首先判断 finalSum 是否为偶数,如果不是,无法拆分,直接返回空列表。
  3. 使用一个变量 i 从 2 开始,表示当前尝试添加的偶数。
  4. 进入循环,只要 finalSum 大于 0:
    a. 尝试从 finalSum 中减去当前的偶数 i
    b. 关键一步:检查减去 i 后的 finalSum。如果 finalSum <= i,这意味着剩余的 finalSum 不足以让我们在下一步添加 i+2(因为需要不同的偶数,且 i+2 > i >= finalSum),或者刚好等于 i(如果加上 i 会导致重复)。为了用尽 finalSum 并保证得到最多数量的偶数,我们将这个剩余的 finalSum 加到当前的 i 上,形成 i + finalSum_remaining。这个合并后的值将是最后一个加入列表的数。然后将 finalSum 设为 0,表示总和已完全分配。
    c. 将(可能被调整过的)i 添加到结果列表 ret 中。
    d. 将 i 增加 2,准备处理下一个偶数。
  5. finalSum 变为 0 时,循环结束,返回列表 ret

这种方法确保了每次都取最小的可用偶数,从而最大化了偶数的数量,并且通过最后一步的合并操作保证了所有数都是不同的正偶数且总和恰好为 finalSum

复杂度分析

  • 时间复杂度: O ( f i n a l S u m ) O(\sqrt{finalSum}) O(finalSum )。 我们依次添加 2, 4, 6, …, k。这些数的和大约是 k 2 / 2 k^2 / 2 k2/2。当和达到 finalSum 时停止,所以 k 2 ≈ 2 × f i n a l S u m k^2 \approx 2 \times finalSum k22×finalSum, 即 k ≈ 2 × f i n a l S u m k \approx \sqrt{2 \times finalSum} k2×finalSum 。循环的次数与 k k k 成正比,因此时间复杂度为 O ( f i n a l S u m ) O(\sqrt{finalSum}) O(finalSum )
  • 空间复杂度: O ( f i n a l S u m ) O(\sqrt{finalSum}) O(finalSum )。 结果列表 ret 最多存储约 f i n a l S u m \sqrt{finalSum} finalSum 个数。

Code

class Solution {public List<Long> maximumEvenSplit(long finalSum) {List<Long> ret = new ArrayList<>();if (finalSum % 2 != 0) {return ret;}long i = 2;while (finalSum > 0) {finalSum -= i;if (finalSum <= i) {i += finalSum;finalSum = 0;}ret.add(i);i += 2;}return ret;}
}

2567. 修改两个元素的最小分数

题目
题目截图 2567

解题思路

贪心

解题过程

题目要求我们通过修改数组中的两个元素,使得数组的“分数”(最大值与最小值的差)最小。我们有两次修改机会。

为了最小化最大值与最小值的差,最优的修改策略总是将待修改的元素值改为与数组中某个“目标”元素相等。由于我们可以修改两个数,我们可以考虑以下几种情况来消除极端值对分数的影响:

  1. 修改两个最大值: 将数组中最大的两个元素修改成与最小值 nums[0] 相等(或者修改成任何小于等于 nums[n-3] 的值)。修改后,数组的实际最大值为 nums[n-3],最小值为 nums[0]。分数是 nums[n-3] - nums[0]
  2. 修改两个最小值: 将数组中最小的两个元素修改成与最大值 nums[n-1] 相等(或者修改成任何大于等于 nums[2] 的值)。修改后,数组的实际最小值为 nums[2],最大值为 nums[n-1]。分数是 nums[n-1] - nums[2]
  3. 修改一个最大值和一个最小值: 将最小值 nums[0] 修改成 nums[1](或更大),并将最大值 nums[n-1] 修改成 nums[n-2](或更小)。修改后,数组的实际最小值为 nums[1],最大值为 nums[n-2]。分数是 nums[n-2] - nums[1]

这三种情况涵盖了通过两次修改来最小化 max - min 的所有有效策略。因为我们总是希望消除最大的数或最小的数对分数的影响。

因此,我们首先对数组进行排序,然后计算上述三种情况对应的分数,取其中的最小值即为答案。

复杂度分析

  • 时间复杂度: O ( N log ⁡ N ) O(N \log N) O(NlogN),主要是数组排序所需的时间。
  • 空间复杂度: O ( log ⁡ N ) O(\log N) O(logN) O ( 1 ) O(1) O(1),取决于排序算法使用的额外空间。

Code

class Solution {public int minimizeSum(int[] nums) {Arrays.sort(nums);int n = nums.length;int maxToMin = nums[n - 3] - nums[0];int minToMax = nums[n - 1] - nums[2];int maxToMinANDminToMax = nums[n - 2] - nums[1];return Math.min(maxToMinANDminToMax, Math.min(maxToMin, minToMax));}
}

1509. 三次操作后最大值与最小值的最小差

题目
题目截图 1509

解题思路

贪心

解题过程

这道题与上一题类似,但我们有三次修改机会。目标仍然是最小化修改后数组的最大值与最小值的差。

同样,最优策略是修改数组中的极端值(最大或最小的那些)。有三次修改机会,意味着我们可以“消除”数组排序后两端的最多三个元素对最终 max - min 差值的影响。考虑以下四种消除极端值的情况:

  1. 修改最大的三个数: 将 nums[n-1], nums[n-2], nums[n-3] 修改掉。剩下的元素范围是 [nums[0], nums[n-4]]。最小差值为 nums[n-4] - nums[0]
  2. 修改最小的三个数: 将 nums[0], nums[1], nums[2] 修改掉。剩下的元素范围是 [nums[3], nums[n-1]]。最小差值为 nums[n-1] - nums[3]
  3. 修改最小的两个数和最大的一个数: 将 nums[0], nums[1]nums[n-1] 修改掉。剩下的元素范围是 [nums[2], nums[n-2]]。最小差值为 nums[n-2] - nums[2]
  4. 修改最小的一个数和最大的两个数: 将 nums[0], nums[n-1]nums[n-2] 修改掉。剩下的元素范围是 [nums[1], nums[n-3]]。最小差值为 nums[n-3] - nums[1]

这四种情况覆盖了所有最优的可能。因为要最小化差值,我们总是改变最大或最小端的元素。改变中间的元素不会比改变两端的元素更优。

所以,先对数组排序。如果数组长度 n 小于或等于 4,我们总能通过三次修改使得所有元素相等,差值为 0。否则,计算上述四种情况的差值,返回其中的最小值。

复杂度分析

  • 时间复杂度: O ( N log ⁡ N ) O(N \log N) O(NlogN), 瓶颈在于排序。
  • 空间复杂度: O ( log ⁡ N ) O(\log N) O(logN) O ( 1 ) O(1) O(1), 取决于排序算法。

Code

class Solution {public int minDifference(int[] nums) {int n = nums.length;if (n <= 4) {return 0;}Arrays.sort(nums);int maxToMin = nums[n - 4] - nums[0];int minToMax = nums[n - 1] - nums[3];int firstTwo = nums[n - 2] - nums[2];int lastTwo = nums[n - 3] - nums[1];int one = Math.min(maxToMin, minToMax);int two = Math.min(firstTwo, lastTwo);return Math.min(one, two);}
}
http://www.xdnf.cn/news/1946.html

相关文章:

  • kafka和Spark-Streaming2
  • [特殊字符]Google放大招!免费高配云主机开仓放粮,手慢无!
  • 详解 Servlet 处理表单数据
  • Linux进程学习【进程状态】
  • 【Linux】进程优先级和进程切换
  • Qt 调试信息重定向到本地文件
  • 深度学习--循环神经网络RNN
  • 自动化必备技能:JSONPath介绍
  • 【粉丝福利社】DeepSeek企业级AI应用实践
  • JPEG 解码 第28次CCF-CSP计算机软件能力认证
  • 《天道》:我发现能压制小人的人,都有一个共同点
  • 2025毕业生必看!用AI工具如何快速生成万字高质量论文
  • SQL Server 2019 安装与配置详细教程
  • Web 服务架构与技术组件概述
  • AI 开发工具提示词集体开源!解锁 Cursor、Cline、Windsurf 等工具的核心逻辑
  • 信创系统上使用 dpkg-repack 工具打包系统已安装软件
  • 用于渗透测试人员的 Burpsuite:Logger++
  • 二重积分的计算
  • 软件设计模式与体系结构:基于Java实现管道-过滤器架构
  • mapbox高阶,使用本地dem数据、等高线面数据实现千里江山图效果
  • Shell脚本-流程控制语句应用案例
  • 从代码学习深度学习 - 微调 PyTorch 版
  • 数据结构初阶:排序
  • 【MySQL专栏】MySQL数据库的复合查询语句
  • Pycharm(六):可变与不可变类型
  • 【时时三省】(C语言基础)循环程序举例
  • 手把手搭建AIGC应用:从图像生成到智能写作全实战
  • 使用 n8n 实现你的第一个爬虫程序:从零到自动化
  • 【金仓数据库征文】- 金融HTAP实战:KingbaseES实时风控与毫秒级分析一体化架构
  • 飞牛 NAS 整机要来了?!