quickly find the median of a sequence of numbers

本文介绍了一种使用最大堆和最小堆的数据结构方法来实时计算输入整数流的中位数。通过维护两个堆之间的平衡,确保了即使在大量数据输入的情况下也能高效地获取当前数据集的中位数。

Question:

Assume the user can enter a large sequence of integer numbers, please return the median of the entered numbers.

Idea: 

Create an min-heap and max-heap, and save the entered number to the heaps and also make sure the heap size difference is less than 1 and the maximum value of max-heap is smaller than or equal to the minimum value of the min-heap.

public class MaxHeap {
	ArrayList<Integer> list = null;
	public MaxHeap() {
		list = new ArrayList<Integer>();
	}
	
	public void insertTop(int value) {
		list.add(value);
		buildMaxHeap();
	}
	
	//get the element with maximum value
	public int getTop() {
		if (list.size() == 0) return Integer.MIN_VALUE;
		return list.get(0);
	}
	// remove the element with maximum value
	public void removeTop() {
		if (list.size() == 0) return;
		list.remove(0);
		buildMaxHeap();
	}
	
	//return the number of elements in the array
	public int size() {
		return list.size();
	}
	
	public void buildMaxHeap() {
		int heapSize = list.size();
	    for (int i = heapSize / 2 - 1; i >= 0; i--) {
	    	maxHeapify(list, i);
	    }
	}

	public void maxHeapify(ArrayList<Integer> heap, int index) {
        int position = index;
        int left = 2 * index + 1;
        int right = 2 * index + 2; 
        
        if(left < heap.size() && heap.get(left) > heap.get(position)) {
            position = left;
        }
        
        if(right < heap.size() && heap.get(right) > heap.get(position)) {
            position = right;
        }
        
        if (position != index) {
            Integer temp = heap.get(position);
            heap.set(position, heap.get(index));
            heap.set(index, temp);
            maxHeapify(heap, position);
        }
    }
}

import java.util.ArrayList;


public class MinHeap {
	ArrayList<Integer> list = null;
	public MinHeap() {
		list = new ArrayList<Integer>();
	}
	//return the number of elements in the array
	public int size() {
		return list.size();
	}
	
	//get the element with minimum value
	public int getTop() {
		if (list.size() == 0) return Integer.MAX_VALUE;
		return list.get(0);
	}
	
	//insert the value into heap
	public void insertTop(int value) {
		list.add(value);
		buildMinHeap();
	}
	// remove the first element
	public void removeTop() {
		if (list.size() == 0) return;
		list.remove(0);
		buildMinHeap();
	}
	
	public void buildMinHeap() {
		int heapSize = list.size();
	    for (int i = heapSize / 2 - 1; i >= 0; i--) {
	    	minHeapify(list, i);
	    }
	}

	public void minHeapify(ArrayList<Integer> heap, int index) {
        int position = index;
        int left = 2 * index + 1;
        int right = 2 * index + 2; 
        
        if(left < heap.size() && heap.get(left) < heap.get(position)) {
            position = left;
        }
        
        if(right < heap.size() && heap.get(right) < heap.get(position)) {
            position = right;
        }
        
        if (position != index) {
            Integer temp = heap.get(position);
            heap.set(position, heap.get(index));
            heap.set(index, temp);
            minHeapify(heap, position);
        }
    }
}

public class Receiver {
	MaxHeap maxHeap = null;
	MinHeap minHeap = null;
	
	public Receiver() {
		maxHeap = new MaxHeap();
		minHeap = new MinHeap();
	}
	// insert the data into the DataSave
	public void insert(int value) {
		if (maxHeap.size() == 0) {
			maxHeap.insertTop(value);
			return;
		}
		if (minHeap.size() == 0) {
			minHeap.insertTop(value);
			return;
		}
		if (maxHeap.size() == minHeap.size()) {
			if (value > maxHeap.getTop()) {
				minHeap.insertTop(value);
			} else {
				maxHeap.insertTop(value);
			}
		} else if (maxHeap.size() > minHeap.size()) {
			if (value >= maxHeap.getTop()) {
				minHeap.insertTop(value);
			} else {
				minHeap.insertTop(maxHeap.getTop());
				maxHeap.removeTop();
				maxHeap.insertTop(value);
			}
		} else {
			if (value >= minHeap.getTop()) {
				maxHeap.insertTop(minHeap.getTop());
				minHeap.removeTop();
				minHeap.insertTop(value);
			} else {
				maxHeap.insertTop(value);
			}
		}
		
	} 
	//get the median
	public float median() {
		if (maxHeap.size() == 0 && minHeap.size() == 0) return Float.MIN_VALUE;
	    if (maxHeap.size() == minHeap.size()) {
	        return (maxHeap.getTop() + minHeap.getTop()) / 2.0f;
	    } else if (maxHeap.size() > minHeap.size()) {
	        return maxHeap.getTop();    
	    } else {
	    	return minHeap.getTop();
	    }
	}
}

blog.youkuaiyun.com/beiyetengqing


基于NSGA-III算法解微电网多目标优化调度研究(Matlab代码实现)内容概要:本文围绕基于NSGA-III算法的微电网多目标优化调度展开研究,重点介绍了如何利用该先进多目标进化算法解决微电网系统中多个相互冲突的目标(如运行成本最小化、碳排放最低、供电可靠性最高等)的协同优化问题。文中结合Matlab代码实现,详细阐述了NSGA-III算法的基本原理、在微电网调度模型中的建模过程、约束条件处理、目标函数设计以及仿真结果分析,展示了其相较于传统优化方法在解高维、非线性、多目标问题上的优越性。同时,文档还提供了丰富的相关研究案例和技术支持背景,涵盖电力系统优化、智能算法应用及Matlab仿真等多个方面。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事能源优化领域的工程技术人员;尤其适合正在进行微电网调度、多目标优化算法研究或撰写相关论文的研究者。; 使用场景及目标:①掌握NSGA-III算法的核心思想及其在复杂能源系统优化中的应用方式;②学习如何构建微电网多目标调度模型并利用Matlab进行仿真解;③为科研项目、毕业论文或实际工程提供算法实现参考和技术支撑。; 阅读建议:建议读者结合文中提供的Matlab代码实例,逐步调试运行并深入理解算法流程与模型构建细节,同时可参考文档中列出的其他优化案例进行横向对比学习,以提升综合应用能力。
### 回答1: 一个 Go 程序,用来查找两个有序数组的中位数,可能如下:func FindMedian(arr1, arr2 []int) float64 { n1 := len(arr1) n2 := len(arr2) if n1 == 0 { return float64(arr2[n2/2]) } if n2 == 0 { return float64(arr1[n1/2]) } if n1 == 1 && n2 == 1 { return float64(arr1[0] + arr2[0]) / 2.0 } if n1 == 1 { if n2 % 2 == 0 { return float64(arr2[n2/2 - 1] + arr2[n2/2]) / 2.0 } else { return float64(arr2[n2/2]) } } if n2 == 1 { if n1 % 2 == 0 { return float64(arr1[n1/2 - 1] + arr1[n1/2]) / 2.0 } else { return float64(arr1[n1/2]) } } i := n1 - 1 j := n2 - 1 var median1, median2 int for i >= 0 && j >= 0 { if arr1[i] > arr2[j] { median1 = arr1[i] i-- } else { median1 = arr2[j] j-- } } if i == -1 { median2 = arr2[j-1] } else { median2 = arr1[i-1] } return float64(median1 + median2) / 2.0 } ### 回答2: 生成一个Go程序来查找两个有序数组的中位数。 首先,我们需要明确中位数的定义。对于一个有序数组,中位数是指位于数组中间位置的元素。如果数组长度为奇数,中位数就是唯一那个中间元素;如果数组长度为偶数,中位数是中间的两个元素的平均值。 接下来,我们可以使用以下步骤生成一个Go程序来找到两个有序数组的中位数: 1. 声明一个函数,例如findMedian,该函数接受两个有序数组作为输入参数。 2. 初始化变量n,用于存储两个有序数组的总长度。 3. 通过将两个有序数组合并为一个新的有序数组,找到中位数所在的位置。可以使用合并排序或使用两个指针的方法来实现这一步骤。 4. 根据总长度n的奇偶性,分别处理中位数的情况: - 如果n为奇数,返回新数组中间位置的元素作为中位数。 - 如果n为偶数,返回新数组中间两个元素的平均值作为中位数。 5. 在主函数中调用findMedian函数,传递两个有序数组作为参数,并打印出中位数结果。 下面是一个示例的Go程序,通过使用合并排序的方法找到两个有序数组的中位数: ```go package main import "fmt" func merge(nums1 []int, nums2 []int) []int { merged := make([]int, len(nums1)+len(nums2)) i, j, k := 0, 0, 0 for i < len(nums1) && j < len(nums2) { if nums1[i] < nums2[j] { merged[k] = nums1[i] i++ } else { merged[k] = nums2[j] j++ } k++ } for i < len(nums1) { merged[k] = nums1[i] i++ k++ } for j < len(nums2) { merged[k] = nums2[j] j++ k++ } return merged } func findMedian(nums1 []int, nums2 []int) float64 { merged := merge(nums1, nums2) n := len(merged) if n%2 == 0 { return float64(merged[n/2-1]+merged[n/2]) / 2.0 } else { return float64(merged[n/2]) } } func main() { nums1 := []int{1, 3} nums2 := []int{2} median := findMedian(nums1, nums2) fmt.Printf("Median is: %.2f", median) } ``` 以上示例展示了如何使用合并排序的方法找到两个有序数组的中位数。你可以根据自己的需进行扩展和修改,以适应其他情况和更复杂的需。 ### 回答3: 下面是一个生成 Go 程序以找到两个有序数组的中位数的示例: ```go package main import ( "fmt" ) func findMedianSortedArrays(nums1 []int, nums2 []int) float64 { m, n := len(nums1), len(nums2) if m > n { nums1, nums2, m, n = nums2, nums1, n, m } imin, imax, half_len := 0, m, (m+n+1)/2 var max_of_left, min_of_right int for imin <= imax { i := (imin + imax) / 2 j := half_len - i if i < m && nums2[j-1] > nums1[i] { imin = i + 1 } else if i > 0 && nums1[i-1] > nums2[j] { imax = i - 1 } else { if i == 0 { max_of_left = nums2[j-1] } else if j == 0 { max_of_left = nums1[i-1] } else { max_of_left = max(nums1[i-1], nums2[j-1]) } break } } if (m+n)%2 == 1 { return float64(max_of_left) } if i == m { min_of_right = nums2[j] } else if j == n { min_of_right = nums1[i] } else { min_of_right = min(nums1[i], nums2[j]) } return float64(max_of_left+min_of_right) / 2.0 } func max(a, b int) int { if a > b { return a } return b } func min(a, b int) int { if a < b { return a } return b } func main() { nums1 := []int{1, 3} nums2 := []int{2} median := findMedianSortedArrays(nums1, nums2) fmt.Printf("The median is: %.2f\n", median) } ``` 这个程序实现了在合并后的有序数组中找到中位数的逻辑。它首先判断数组的大小,然后使用二分查找的方法从较小的数组开始分割,保证左边的元素数量等于右边(或比右边多1)。然后通过比较左侧的最大值和右侧的最小值来确定中位数。如果数组长度是奇数,则直接返回中位数的值;如果是偶数,则计算左侧最大值和右侧最小值的平均值作为中位数的值。 在 main 函数中,我们定义了两个示例的有序数组 `nums1` 和 `nums2`,然后调用 `findMedianSortedArrays` 函数计算它们的中位数,并打印结果。 请注意,这只是一个示例程序,您可以根据自己的需进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值