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

两种方法解决「将数组和减半的最少操作次数」

在这里插入图片描述
解决这个问题的关键是:每次必须选择当前最大的元素减半。

如果要高效地 “每次获取最大元素”,大根堆无疑是最佳选择。

方法 1:用 PriorityQueue 实现

使用 Java 内置的PriorityQueue作为大根堆,直接存储double类型的元素。

public static int halveArray(int[] nums) {// 大根堆:通过比较器(b.compareTo(a))实现,确保堆顶是最大元素PriorityQueue<Double> heap = new PriorityQueue<>((a, b) -> b.compareTo(a));double sum = 0;// 计算数组总和,并将所有元素加入大根堆for (int num : nums) {heap.add((double) num);sum += num;}// 减少的总量至少为原总和的一半sum /= 2;int ans = 0;double minus = 0; // 累计减少的总量// 每次取最大元素减半,直到累计减少量≥目标while (minus < sum) {ans++; // 操作次数+1double cur = heap.poll() / 2; // 取出最大元素,减半minus += cur; heap.add(cur); // 减半后的元素放回堆中}return ans;
}

方法 2:自定义大根堆(用整数避免浮点数精度问题)

使用自定义的大根堆,并且用long类型存储元素(通过左移 20 位放大元素),避开浮点数精度陷阱。

public int halveArray(int[] nums) {int n = nums.length;long[] heap = new long[n];long sum = 0;for (int i = n - 1; i >= 0; i--) {// 放大2^20倍(足够覆盖1e9的精度,避免浮点数)heap[i] = (long) nums[i] << 20;sum += heap[i];heapify(heap, n, i);}sum /= 2;int ans = 0;long minus = 0;while (minus < sum) {ans++;// 堆顶减半(整数操作,无精度问题)heap[0] >>= 1; // 右移1位 = 除以2,比/=2更快minus += heap[0];// 调整堆顶heapify(heap, n, 0);}return ans;}private void heapify(long[] heap, int size, int i) {// 暂存当前节点值,避免重复访问heap[i]long curVal = heap[i];// 左孩子索引int left = i * 2 + 1;while (left < size) {// 暂存左孩子值,减少数组访问long leftVal = heap[left];// 右孩子值:存在则取,不存在则设为极小值(不影响比较)long rightVal = (left + 1 < size) ? heap[left + 1] : Long.MIN_VALUE;//选左右孩子中更大的那个int largerChild = (rightVal > leftVal) ? left + 1 : left;long largerVal = (largerChild == left) ? leftVal : rightVal;//若当前节点值 >= 较大孩子值,堆结构已满足,退出if (curVal >= largerVal) {break;}//直接将较大孩子值覆盖到当前节点heap[i] = largerVal;// 更新当前节点索引,继续向下调整i = largerChild;left = i * 2 + 1;}//将暂存的当前节点值放到最终位置heap[i] = curVal;}

完整代码
链接:https://pan.quark.cn/s/2ed207e367ac
提取码:3H47

http://www.dtcms.com/a/453778.html

相关文章:

  • AI 与 Agent 技术体系知识图谱
  • 线性表的顺序和链式存储
  • 活动策划网站源码广西住房城乡建设领域
  • 做彩票网站犯法吗wordpress 标题颜色
  • 怎么科研绘图?怎么批量搜索高质量文献?Nature, Science, Cell
  • [hpatch]差分算法学习笔记 -- patch解压补丁
  • STM32G474 STM32CubeMX SPL06-001驱动程序
  • 域名注册好怎么建设网站工作态度和责任心感悟
  • 网站充值链接怎么做php网站空间支持
  • 做网站商城如何优化3 阐述网站建设的步骤过程 9分
  • 沈阳建网站公司wordpress posts page
  • [论文阅读] 软件工程 | 量子计算即服务(QCaaS)落地难?软件工程视角的解决方案来了
  • 上海网站建设的企哪些网站可以直接做英文字谜
  • 北京网站建设模板主题做一个小游戏要多少钱
  • jsx加密详解
  • 网站导航如何用响应式做管理咨询公司收费标准
  • 自助建站网站源码网站被百度k
  • 整体设计 逻辑系统程序 之15 Go 语言 / For 语句 / Do 句子
  • 贵阳工程建设招聘信息网站推广方式英文
  • 对称破局:双变量求值镜像之道
  • 智慧物流教师赛的意义:培养适应行业发展的新型教师
  • VBA之Word应用第四章第三节:段落集合Paragraphs对象的方法(一)
  • 微企点网站建设如何学习网站开发编程
  • 住房和城乡建设部网站买卖合同汽车拆车件网上商城
  • Sourcetree克隆/获取gitee工程,Git获取SSH密钥
  • 保定 网站制作 招聘wordpress图片清理
  • C++网络编程(四)文件描述符
  • Nginx+Keepalived高可用部署
  • 网站建设费用表格做网站 用 显示器
  • 【学习K230-例程47】GT6700-视频播放实验