金条分割问题:
采用优先级队列实现的,这里的优先级队列默认按照最小堆生成。所以可以不用定义比较器。等价--如注释
如果需要大根堆的话,就需要定义比较器。
package day5; import java.util.Arrays; import java.util.Comparator; import java.util.PriorityQueue; /* * 一块金条切两块,需要花费和长度数值一样的铜板。怎么分最省铜板。 * eg: 给定数组{10,20,30}代表三个人,整块金条长度就是10+20+30=60, * 分成数组中的10,20,30三个部分。最优解是先分30+40 再分10+20共需90个铜板 * * 实质是哈夫曼编码,每次取出两个最小的相加相加放回数组,依次进行到数组元素只剩下一个 * 此时就是最小代价 * * 知道但是不会编码,就很尬了 * * !!!!!!!知识点:!!!!!!!!!!! * 这种在数组中取最大、最小再放回的,考虑堆结构。 * 当总和可以表示成分的和或者乘的时候,考虑哈弗曼编码 * */ public class Code03_GoldBarSegmentation { public static void main(String[] args) { int arr[] = {10,20,30}; System.out.println(Hoffmann(arr )); } public static class minHeapComparator implements Comparator<Integer>{ @Override public int compare(Integer arg0, Integer arg1) { return arg0 - arg1; } } public static int Hoffmann(int arr []) { //PriorityQueue<Integer> minHeap = new PriorityQueue<>(); PriorityQueue<Integer> minHeap = new PriorityQueue<>(new minHeapComparator()); for(int i = 0 ; i <arr.length ;i ++) { minHeap.add(arr[i]); } int sum =0; while(minHeap.size() >1) { int cur = minHeap.poll()+minHeap.poll(); sum += cur; minHeap.add(cur); } return sum; } }
最小堆实现:
// 自己堆快忘了,手写一个,复习 // 从小到大排序,需要大根堆实现 // 从大到小排序,用小根堆实现 /* * 小根堆: * hoopinsert:加入一个新节点,调整(向上) * heapify:一个数变大之后往下调,往下调,往下调 * 1.左右孩子是否存在? * 2、找到左右孩子中最小的那个,跟当前节点比较,若小就交换,否在停止 heapSort */ public static class MyHeap { public static void swap(int arr[], int i, int j) { int temp = arr[j]; arr[j] = arr[i]; arr[i] = temp; } public static void heapify(int arr[], int size, int index) { int left = index * 2 + 1; while (left < size) {// 保证孩子存在 // 保证右孩子存在的情况下 int childmin = (left + 1 < size && arr[left + 1] < arr[left]) ? left + 1 : left; childmin = arr[childmin] < arr[index] ? childmin : index; if (childmin == index) break; swap(arr, childmin, index); index = childmin; left = index * 2 + 1; } } public static void hoopinsert(int arr[], int index) { int father = (index - 1) / 2; while (arr[father] > arr[index]) { swap(arr, father, index); index = father; father = (index - 1) / 2; } } public static void heapSort(int arr[]) { if (arr == null || arr.length < 2) return; // 建立小根堆 for (int i = 0; i < arr.length; i++) { hoopinsert(arr, i); } // 排序,需要从小根堆中每次取堆顶,然后跟最后一个数交换。size-1,重新排一遍。 //将size = arr.length-1 , --size换成--size,跑出来结果是错的。 //没弄明白 int size = arr.length; swap(arr, --size, 0); while (size > 0) { heapify(arr, size, 0); swap(arr, --size, 0); } } // for test 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) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); } return arr; } public static int[] copyArray(int arr[]) { if (arr == null) { return null; } int[] res = new int[arr.length]; for (int i = 0; i < arr.length; i++) { res[i] = arr[i]; } return res; } public static void print(int arr[]) { for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); } public static void comparator(int arr[]) { Arrays.sort(arr); for (int i = 0 ; i <arr.length/2;i ++) { swap(arr,i,arr.length-1-i); } } public static boolean isEqual(int arr[], int res[]) { if ((arr == null && res != null) || (arr != null && res == null)) return false; if (arr == null && res == null) return true; if (arr.length != res.length) return false; for (int i = 0; i < arr.length; i++) { if (arr[i] != res[i]) return false; } return true; } public static void main(String[] args) { int maxSize = 30; int maxValue = 100; int testTime = 1000; boolean suceed = true; //int arr[] = { 6, 12, 3, 8, 4, 1, 2, 9 }; //heapSort(arr); //print(arr); for (int i = 0; i < testTime; i++) { int[] arr1 = generateRandomArray(maxSize, maxValue); int[] arr2 = copyArray(arr1); heapSort(arr1); comparator(arr2); if (!isEqual(arr1, arr2)) { suceed = false; // System.out.println("********************"); print(arr1); print(arr2); break; } } System.out.println(suceed ? "Nice!" : "Flucking Fucked !"); } }
遇到一个问题:
我本来想将自己写的堆放到金条分隔中使用,于是就直接把 MyHeap类 放进了GoldBarSegmentation类 里面,没写GoldBarSegmentation类 的主函数,运行MyHeap类成功后写了删掉 MyHeap类主函数,写GoldBarSegmentation类 主函数之后提示“找不到或无法加载主类 ”。即后写的主函数不被识别,即使是删掉MyHeap类,用自带的优先级队列也不行。
方法:
应该是eclipse在第一运行程序的时候记住了一些东西。通过 菜单栏 ——> run ——>run Configurations 打开后在左侧找到对应的程序名,右击delect。
再次重新运行就可以了。