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

每日算法-250420

每日算法 - 2025/04/20

记录一下今天刷的几道 LeetCode 题目。

3075. 幸福值最大化的选择方案

题目描述
Problem 3075 Description

思路

贪心

解题过程

核心思想是:为了总幸福值最大化,我们应该优先选择当前能提供最大幸福值的孩子。

  1. 排序:将 happiness 数组降序排序。这样,每次我们考虑的就是当前可选孩子中幸福值最高的。
  2. 选择与更新:我们总共需要选择 k 个孩子。
    • 选择当前幸福值最高的孩子(排序后的数组从左到右选择)。
    • 设我们已经选择了 i 个孩子(i 从 0 开始计数),那么在选择第 i+1 个孩子时,他的原始幸福值 happiness[i] 会因为前面已经选择了 i 个孩子而减少 i
    • 所以,第 i+1 个孩子(数组索引为 i)实际贡献的幸福值是 max(0, happiness[i] - i),因为幸福值不能为负数。
    • 累加这个实际贡献的幸福值。
  3. 迭代:重复步骤 2,直到选满 k 个孩子或者所有可选孩子的实际幸福值都变为 0。

复杂度

  • 时间复杂度: O ( N log ⁡ N ) O(N \log N) O(NlogN),主要由排序决定,其中 N 是 happiness 数组的长度。
  • 空间复杂度: O ( log ⁡ N ) O(\log N) O(logN) O ( N ) O(N) O(N),取决于排序算法使用的栈空间或辅助空间。如果只考虑额外空间(不计输入数组的修改),可以认为是 O ( 1 ) O(1) O(1)

Code

class Solution {public long maximumHappinessSum(int[] happiness, int k) {// 对幸福值数组进行升序排序Arrays.sort(happiness);int n = happiness.length;long maxHappinessSum = 0;int turns = 0; // 记录已经选择了多少个孩子 (即轮数)// 从幸福值最高的孩子开始选择 (数组末尾)for (int i = n - 1; i >= 0 && k > 0; i--) {// 计算当前孩子实际能贡献的幸福值// 原始幸福值 happiness[i] 需要减去已经进行的轮数 turnslong currentHappiness = happiness[i] - turns;// 幸福值不能小于 0if (currentHappiness > 0) {maxHappinessSum += currentHappiness;} else {// 如果当前最大幸福值的孩子贡献都 <= 0,后续的更不可能 > 0break;}turns++; // 轮数增加k--;     // 还需要选择的孩子数量减少}return maxHappinessSum;}
}

2554. 从一个范围内选择最多整数 I

题目描述
Problem 2554 Description

思路

贪心

解题过程

目标是在不超过 maxSum 的前提下,从范围 [1, n] 中选择尽可能多的、不在 banned 列表中的整数。

  1. 贪心策略:为了选择最多的整数,我们应该优先选择数值最小的整数,因为它们消耗的 maxSum 最少。
  2. 排除禁用数:使用一个数组来快速判断一个数是否在 banned 列表中。
  3. 迭代选择:从 1 开始,依次检查每个整数 i1 <= i <= n):
    • 如果 i 不在 banned 列表中。
    • 并且当前 maxSum大于0
    • 那么就选择 i,增加计数 ret,并更新 maxSum -= i
  4. 返回结果:最终的 ret 就是最多能选择的整数数量。

复杂度

  • 时间复杂度: O ( B + n ) O(B + n) O(B+n),其中 B 是 banned 数组的长度(构建哈希表或标记数组),n 是上限范围(遍历 1n)。
  • 空间复杂度: O ( B ) O(B) O(B) 如果使用 HashSet,或者 O ( S ) O(S) O(S) 如果使用大小为 S (如 10001 或 n+1) 的数组来标记 banned 数字。

Code

class Solution {public int maxCount(int[] banned, int n, int maxSum) {int size = 10001;int[] hash = new int[size];for (int x : banned) {hash[x]++;}int ret = 0, sum = 0;for (int i = 1; i <= n && maxSum >= 0; i++) {if (hash[i] == 0) {ret++;maxSum -= i;}}return maxSum < 0 ? ret - 1 : ret;}
}

1283. 使结果不超过阈值的最小除数

题目描述
Problem 1283 Description

这是第二次做这道题,思路已经比较清晰了。详细题解可以参考之前的笔记 每日算法-250408。

Code

class Solution {public int smallestDivisor(int[] nums, int threshold) {Arrays.sort(nums);int left = 1, right = nums[nums.length - 1];while (left <= right) {int mid = left + (right - left) / 2;if (check(nums, mid, threshold)) {right = mid - 1;} else {left = mid + 1;}}return left;}private boolean check(int[] arr, int divisor, int k) {int sum = 0;for (int i = 0; i < arr.length; i++) {if (arr[i] % divisor == 0) {sum += arr[i] / divisor;} else {sum += arr[i] / divisor;sum++;}}return sum <= k;}
}

相关文章:

  • qwen 32B 模型配置文件参数解释;48 个堆叠的解码器层是什么意思; `max_window_layers`的作用; 定义 `device_map`
  • 文件上传漏洞:Pass-01
  • Linux安装mysql_exporter
  • UE虚幻4虚幻5动画蓝图调试,触发FellOutOfWorld事件和打印输出,继续DeepSeek输出
  • C++学习之游戏服务器开发⑩ZINX的TCP通道实现
  • 机制的作用
  • Origin将双Y轴柱状图升级为双向分组柱状图
  • 在 Ubuntu 系统上安装 PostgreSQL
  • Arduino示例代码讲解:Project 08 - Digital Hourglass 数字沙漏
  • javascript day4
  • C语言之图像文件的属性
  • Java(自用查看版)
  • Towards Transferable Targeted 3D Adversarial Attack in the Physical World--阅读笔记
  • 头歌实训之连接查询
  • 【网络编程】从零开始彻底了解网络编程(二)
  • 【2025计算机网络-面试常问】http和https区别是什么,http的内容有哪些,https用的是对称加密还是非对称加密,流程是怎么样的
  • wordpress独立站的产品详情页添加WhatsApp链接按钮
  • 深入探索 Unix 与 Linux:历史、内核及发行版
  • 02_解决Class com.sun.tools.javac.tree.JCTree
  • 【失败总结】Win10系统安装docker
  • 电子产品已拆封,还能申请“七天无理由退货”吗?上海法院这样判
  • 人民网评:官方轻踩刹车,智能驾驶不能“蒙眼狂奔”
  • 河南一季度GDP为14945.58亿元,同比增长5.9%
  • 一代油画家的“色彩之诗”:周碧初捐赠艺术展上海举行
  • 亚马逊云:中国企业开始以“行业集群”的方式出海
  • 我国博士后已超40万人,2024年招收人数再创新高