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

每日算法-250423

每日算法学习记录 - 2023年4月25日

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


LeetCode 3301. 高度互不相同的最大塔高和

题目描述
题目图片

思路

贪心

解题过程 (基于提供的代码逻辑)

代码首先对 maximumHeight 数组进行排序。然后从后往前遍历。

  1. 初始化总和 sum 为排序后最后一个元素(被视为最高的塔)。
  2. 从倒数第二个元素开始向前遍历 (in-20)。
  3. 如果 maximumHeight[i] < maximumHeight[i + 1] (排序后),则当前塔的高度可以直接设为 maximumHeight[i] 并加入 sum
  4. 否则(即 maximumHeight[i] >= maximumHeight[i + 1]),为了满足某种递减约束(比如高度必须比后一个塔低至少1),将当前塔的高度强制设为 maximumHeight[i + 1] - 1,并将其加入 sum。同时更新 maximumHeight[i] 的值为 maximumHeight[i + 1] - 1 以影响下一个迭代。
  5. 在每次设置高度后,检查 maximumHeight[i] 是否小于等于 0。如果是,则认为无法构成有效序列,返回 -1。
  6. 遍历完成后,返回计算出的总和 sum

复杂度

  • 时间复杂度: O ( N log ⁡ N ) O(N \log N) O(NlogN),主要是排序的开销。
  • 空间复杂度: O ( 1 ) O(1) O(1) (假设排序为原地排序,不考虑递归栈空间)或 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 maximumTotalSum(int[] maximumHeight) {Arrays.sort(maximumHeight);int n = maximumHeight.length;long sum = maximumHeight[n - 1];for (int i = n - 2; i >= 0; i--) {if (maximumHeight[i] < maximumHeight[i + 1]) {sum += maximumHeight[i];} else {sum += maximumHeight[i + 1] - 1;maximumHeight[i] = maximumHeight[i + 1] - 1;}if (maximumHeight[i] <= 0) {return -1;}}return sum;}
}

LeetCode 945. 使数组唯一的最小增量

题目描述
题目图片

思路

贪心

解题过程

目标是使得数组中所有元素唯一,并且总的增量最小。

  1. 排序:首先对数组 nums 进行升序排序。排序后,重复的元素或需要调整的元素会相邻出现。
  2. 遍历与调整:从数组的第二个元素 (i = 1) 开始遍历。
  3. 检查冲突:比较当前元素 nums[i] 与其前一个元素 nums[i - 1]
  4. 处理冲突:如果 nums[i - 1] >= nums[i],说明 nums[i] 的值小于或等于前一个元素,违反了唯一性(或者说,为了后续元素更容易唯一化,我们希望它至少比前一个大1)。此时,需要将 nums[i] 增加到 nums[i - 1] + 1
  5. 计算增量:需要增加的值是 (nums[i - 1] + 1) - nums[i]。将这个增量累加到总计数 count 中。
  6. 更新数组:将 nums[i] 的值更新为 nums[i - 1] + 1。这一步是关键,因为它确保了当前元素相对于 调整后 的前一个元素是唯一的,并且为后续元素的调整奠定了基础(保证了数组在该点及之前的部分局部有序且满足 nums[i] > nums[i-1])。
  7. 遍历结束后,count 即为所需的最小总增量。

为什么要加上 > 的判断(即 nums[i-1] >= nums[i])?因为 nums[i-1] 可能在之前的步骤中被增加过,即使原始的 nums[i] 大于原始的 nums[i-1],增加后的 nums[i-1] 仍可能大于或等于当前的 nums[i]

复杂度

  • 时间复杂度: O ( N log ⁡ N ) O(N \log N) O(NlogN),瓶颈在于排序。
  • 空间复杂度: O ( 1 ) O(1) O(1) (辅助空间)。

Code

class Solution {public int minIncrementForUnique(int[] nums) {int count = 0;Arrays.sort(nums);for (int i = 1; i < nums.length; i++) {if (nums[i - 1] >= nums[i]) {count += nums[i - 1] + 1 - nums[i];nums[i] = nums[i - 1] + 1;}}return count;}
}

LeetCode 1846. 减小和重新排列数组后的最大元素

题目描述
题目图片

思路

贪心

解题过程

目标是在满足以下两个条件的前提下,最大化数组中的最大元素:

  1. 数组第一个元素必须是 1。
  2. 任意相邻两个元素的差的绝对值不能超过 1 (abs(arr[i] - arr[i-1]) <= 1)。

为了让最终的最大元素尽可能大,我们应该让数组元素尽可能地形成一个递增序列,且相邻元素差尽可能为 1。

  1. 排序:首先对数组 arr 进行升序排序。这使得我们可以更容易地处理相邻元素的差值约束。
  2. 设置首元素:根据条件 1,将排序后的数组第一个元素 arr[0] 强制设置为 1。
  3. 遍历与调整:从数组的第二个元素 (i = 1) 开始遍历。
  4. 应用约束:根据条件 2,arr[i] 必须满足 arr[i] <= arr[i-1] + 1。由于数组已经排序,arr[i] >= arr[i-1] 总是成立的,所以我们只需要确保 arr[i] 不会比 arr[i-1] + 1 大太多。如果 arr[i]arr[i-1] + 1 大(即 arr[i] - arr[i-1] > 1),为了满足约束且尽可能保持 arr[i] 的值大,我们将 arr[i] 减小到 arr[i-1] + 1。如果 arr[i] - arr[i-1] <= 1,则 arr[i] 保持不变,因为它已经满足条件。
  5. 结果:经过这样的调整,数组满足了所有条件,并且每个元素都被设置为在满足约束下的最大可能值。因此,数组的最后一个元素 arr[n-1] 就是可以得到的最大元素。

复杂度

  • 时间复杂度: O ( N log ⁡ N ) O(N \log N) O(NlogN),主要是排序的开销。
  • 空间复杂度: O ( 1 ) O(1) O(1) (辅助空间)。

Code (Java)

class Solution {public int maximumElementAfterDecrementingAndRearranging(int[] arr) {Arrays.sort(arr);int n = arr.length;arr[0] = 1;for (int i = 1; i < n; i++) {if (arr[i] - arr[i - 1] > 1) {arr[i] = arr[i - 1] + 1;}}return arr[n - 1];}
}

LeetCode 3143. 正方形中的最多点数(复习)

题目描述
题目图片

复习说明

这是第二次做这道题。这次做得更好,但仍然需要注意细节,比如坐标可能是负数,这会影响边界计算和点是否在正方形内的判断。使用 Math.abs() 处理坐标是关键。

详细题解可以参考之前的笔记:每日算法-250411

Code

class Solution {private int count = 0;public int maxPointsInsideSquare(int[][] points, String ss) {char[] s = ss.toCharArray();int left = 0, right = 0;for (int[] point : points) {right = Math.max(right, Math.max(Math.abs(point[0]), Math.abs(point[1])));}while (left <= right) {int mid = left + (right - left) / 2;if (check(points, mid, s)) {left = mid + 1;} else {right = mid - 1;}}return count;}private boolean check(int[][] arr, int len, char[] s) {int tmpCount = 0;int[] hash = new int[26];for (int i = 0; i < arr.length; i++) {int x = Math.abs(arr[i][0]), y = Math.abs(arr[i][1]);char ch = s[i];if (x <= len && y <= len) {hash[ch - 'a']++;if (hash[ch - 'a'] > 1) {return false;}tmpCount++;}}count = Math.max(count, tmpCount);return true;}
}

相关文章:

  • VR 全景看车的独特优势​
  • 从0到1掌握机器学习核心概念:用Python亲手构建你的第一个AI模型(超多代码+可视化)
  • 具身智能操作知识梳理与拓展
  • Springfox + Swagger 的完整配置及同类框架对比的详细说明
  • JavaScript 渲染内容爬取:Puppeteer 高级技巧与实践
  • 服务器-conda下载速度慢-国内源
  • Unity进阶课程【五】WebGL 打包文件本地运行报错解决 - 局域网、无限制人数、本地服务
  • 【白雪讲堂】GEO优化第6篇 内容中台的搭建:GEO优化的中控神经系统
  • 使用 Conda 创建新环境
  • MAGI-1自回归式大规模视频生成
  • Linux的进程间通信
  • Docker配置带证书的远程访问监听
  • 身份证实名认证:通往数字安全与便捷生活的钥匙
  • 璞华ChatBI闪耀2025数博会:对话式数据分析引领数智化转型新范式
  • Jmeter中同步定时器使用注意点
  • 元素滚动和内容垂直居中同时存在,完美的 html 元素垂直居中的方法flex + margin: auto
  • IP地址与子网掩码
  • IDEA add gitlab account 提示
  • Windows 同步技术-一次性初始化
  • 一文读懂https
  • 山西国道塌方致55岁货车司机死亡,女儿:货车的车贷还要还
  • 从“龙队”到“龙副”,国乒这批退役球员为何不爱当教练了
  • 特朗普:无意解雇鲍威尔,但美联储应该降低利率
  • 中国英国商会政府事务主席陶克瑞:重庆经济成就瞩目,中英合作机遇无限
  • 聚焦客户真实需求,平安人寿重磅推出“添平安”保险+服务解决方案
  • 湖南平江发生人员溺亡事件,已造成4人死亡