贪心算法——哈夫曼编码树

简介: 贪心算法——哈夫曼编码树

题目

一块金条切成两半,是需要花费和长度数值一样的铜板的。比如长度为20的金条,不管怎么切,都要花费20个铜板。一群人想整分整块金条,怎么分最省铜板?

例如,给定数组{10,20,30},代表一共三个人,整块金条长度为60,金条要分成10,20, 30三个部分。如果先把长度60的金条分成10和50,花费60;再把长度50的金条分成20和30,花费50;一共花费110铜板。但如果先把长度60的金条分成30和30,花费60;再把长度30金条分成10和20,花费30;一共花费90铜板。输入一个数组,返回分割的最小代价。

贪心算法最常用的两个套路是堆跟排序,一般贪心算法的核心代码都很少,所以很少在笔试时候要你用贪心来解决某个问题。如果用暴力解通过对数器来验证贪心的正确性就另说了,但是跟贪心有关的核心代码都很少。

image.png

package com.harrison.class09;
import java.util.PriorityQueue;
public class Code04_LessMoneySplitGold {
  // 贪心解法
  public static int lessMoney1(int[] arr) {
    PriorityQueue<Integer> pQ = new PriorityQueue<>();
    for (int i = 0; i < arr.length; i++) {
      pQ.add(arr[i]);
    }
    int cur = 0;
    int sum = 0;
    while (pQ.size() > 1) {
      cur = pQ.poll() + pQ.poll();
      sum += cur;
      pQ.add(cur);
    }
    return sum;
  }
  // 纯暴力!
  public static int lessMoney2(int[] arr) {
    if (arr == null || arr.length == 0) {
      return 0;
    }
    return process2(arr, 0);
  }
  // 等待合并的数都在arr里,pre之前的合并行为产生了多少总代价
  // arr中只剩一个数字的时候,停止合并,返回最小的总代价
  public static int process2(int[] arr, int pre) {
    if (arr.length == 1) {
      return pre;
    }
    int ans = Integer.MAX_VALUE;
    for (int i = 0; i < arr.length; i++) {
      for (int j = i + 1; j < arr.length; j++) {
        ans = Math.min(ans, process2(copyAndMergeTwo(arr, i, j), pre + arr[i] + arr[j]));
      }
    }
    return ans;
  }
  public static int[] copyAndMergeTwo(int[] arr, int i, int j) {
    int[] ans = new int[arr.length - 1];
    int ansi = 0;
    for (int arri = 0; arri < arr.length; arri++) {
      if (arri != i && arri != j) {
        ans[ansi++] = arr[arri];
      }
    }
    ans[ansi] = arr[i] + arr[j];
    return ans;
  }
  public static int[] generateRandomArray(int maxSize, int maxValue) {
    int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
    for (int i = 0; i < arr.length; i++) {
      arr[i] = (int) (Math.random() * (maxValue + 1));
    }
    return arr;
  }
  public static void main(String[] args) {
    int testTime = 100000;
    int maxSize = 6;
    int maxValue = 1000;
    for (int i = 0; i < testTime; i++) {
      int[] arr = generateRandomArray(maxSize, maxValue);
      if (lessMoney1(arr) != lessMoney2(arr)) {
        System.out.println("Oops!");
      }
    }
    System.out.println("finish!");
  }
}
相关文章
|
3月前
|
存储 算法 C语言
"揭秘C语言中的王者之树——红黑树:一场数据结构与算法的华丽舞蹈,让你的程序效率飙升,直击性能巅峰!"
【8月更文挑战第20天】红黑树是自平衡二叉查找树,通过旋转和重着色保持平衡,确保高效执行插入、删除和查找操作,时间复杂度为O(log n)。本文介绍红黑树的基本属性、存储结构及其C语言实现。红黑树遵循五项基本规则以保持平衡状态。在C语言中,节点包含数据、颜色、父节点和子节点指针。文章提供了一个示例代码框架,用于创建节点、插入节点并执行必要的修复操作以维护红黑树的特性。
102 1
|
14天前
|
算法
树的遍历算法有哪些?
不同的遍历算法适用于不同的应用场景。深度优先搜索常用于搜索、路径查找等问题;广度优先搜索则在图的最短路径、层次相关的问题中较为常用;而二叉搜索树的遍历在数据排序、查找等方面有重要应用。
22 2
|
1月前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
22 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
2月前
|
大数据 UED 开发者
实战演练:利用Python的Trie树优化搜索算法,性能飙升不是梦!
在数据密集型应用中,高效搜索算法至关重要。Trie树(前缀树/字典树)通过优化字符串处理和搜索效率成为理想选择。本文通过Python实战演示Trie树构建与应用,显著提升搜索性能。Trie树利用公共前缀减少查询时间,支持快速插入、删除和搜索。以下为简单示例代码,展示如何构建及使用Trie树进行搜索与前缀匹配,适用于自动补全、拼写检查等场景,助力提升应用性能与用户体验。
56 2
|
1月前
|
存储 算法
数据结构与算法学习十六:树的知识、二叉树、二叉树的遍历(前序、中序、后序、层次)、二叉树的查找(前序、中序、后序、层次)、二叉树的删除
这篇文章主要介绍了树和二叉树的基础知识,包括树的存储方式、二叉树的定义、遍历方法(前序、中序、后序、层次遍历),以及二叉树的查找和删除操作。
25 0
|
1月前
|
存储 算法 Java
数据结构和算法--分段树
数据结构和算法--分段树
16 0
|
3月前
|
算法 5G vr&ar
基于1bitDAC的MU-MIMO的非线性预编码算法matlab性能仿真
在现代无线通信中,1-bit DAC的非线性预编码技术应用于MU-MIMO系统,旨在降低成本与能耗。本文采用MATLAB 2022a版本,深入探讨此技术,并通过算法运行效果图展示性能。核心代码支持中文注释与操作指导。理论部分包括信号量化、符号最大化准则,并对比ZF、WF、MRT及ADMM等算法,揭示了在1-bit量化条件下如何优化预编码以提升系统性能。
|
3月前
|
算法
【Azure Developer】完成算法第4版书中,第一节基础编码中的数组函数 histogrm()
【Azure Developer】完成算法第4版书中,第一节基础编码中的数组函数 histogrm()
|
4月前
|
机器学习/深度学习 存储 算法
编码之舞:从算法到应用的探索之旅
在数字化时代的浪潮中,编程技术如同一种语言,连接着人类与机器。本文将带领读者踏上一场自数据结构基础至高级算法应用的探索旅程,通过实际案例分析,揭示算法在现代软件开发中的重要作用,并分享作者在编程实践中的心得体会,旨在为初学者和资深开发者提供有价值的参考与启示。
下一篇
无影云桌面