面试题71:数据流中的中位数
来源:互联网 发布:房源软件哪个好 编辑:程序博客网 时间:2024/04/26 02:59
解法一:
先存数组,再排序(效率很低)
解法二:
先存数组,再冒泡排序排一半(效率同样很低)
解法三:(推荐)
先存数组,利用partition函数原理,如果partition返回的index刚好是数组长度的一半,那么这个index对应的数就是中位数啦。
时间复杂度:O(n)
#include<iostream>using namespace std;int Partition(int *arr, int start, int end) //此处end为最后一个元素对应下标{if (start == end) return start;int pivot = arr[end];int first = start-1; //始终指向分好部分最后一个小于pivot的元素for (int second = start; second < end; ++second){if (arr[second] < pivot){first++; //让其指向第一个比pivot大的元素if(first!=second) swap(arr[first], arr[second]);}}++first;swap(arr[first], arr[end]);return first;}void QuickSort(int *arr, int start, int end){if (start == end) return;int index = Partition(arr, start, end);if (index>start) QuickSort(arr, start, index - 1);if (index < end) QuickSort(arr, index + 1, end);}/*注意:此方法也可以用来查找最小的k个数*/int GetMedium(int *arr, int size){int start = 0;int end = size - 1;int index = Partition(arr, start, end);int midIndex = (size + 1) / 2 - 1; //下标while (index != midIndex){if (index > midIndex){end = index - 1;index = Partition(arr, start, end);}else{start = index + 1;index = Partition(arr, start, end);}}return arr[index];}int main() {int arr[] = { 2,5,9,7,1,6,4,8,3 };cout << GetMedium(arr, 9)<<endl;QuickSort(arr, 0, 8);for (int i = 0; i < 9; i++)cout << arr[i] << " ";cout << endl;return 0;}
补充:
解法四:(方法好,实现困难)
可以建立AVL树,通常AVL树的平衡因子是左右子树的高度差,可以将平衡因子修改为左右子树的结点差,这样时间复杂度为O(lgn)。且只需要遍历一次数组。
解法五:(方法好,实现容易)
用一个最大堆和最小堆也可以实现。用一个最大堆存放左边较小的数,用一个最小堆存放右边较大的数。现在关键是如何保证数据平均分配到两个堆中,使两个堆中数据数目之差不能超过1。
可以在数据的总数目是偶数时把心数据插入到最小堆,否则插入到最大堆。如果这个新插入到最小堆的数据比最大堆中的一些数据还要小,则可以先将该数据插入到最大堆,然后将最大堆中的最大数拿出插入到最小堆。
#include <iostream> #include <vector> #include <stack>#include <algorithm> //堆算法#include <functional> //仿函数using namespace std;void InsertData(vector<int>&minHeap, vector<int>&maxHeap,int data){if (((minHeap.size() + maxHeap.size()) & 1) == 0) //插入的总数目是奇数时,插入到最大堆{if (minHeap.size() > 0 && data > minHeap[0]){minHeap.push_back(data);push_heap(minHeap.begin(), minHeap.end(), greater<int>()); //插入元素后进行调整data = minHeap[0];pop_heap(minHeap.begin(), minHeap.end(), greater<int>());//把最小的元素放到最后,并调整minHeap.pop_back(); //去掉最后的元素,即最小的那个元素}maxHeap.push_back(data);push_heap(maxHeap.begin(), maxHeap.end(), less<int>());}else //插入的总数目是偶数时,插入到最小堆{if (maxHeap.size() > 0 && data < maxHeap[0]){maxHeap.push_back(data);push_heap(maxHeap.begin(), maxHeap.end(), less<int>());data = maxHeap[0];pop_heap(maxHeap.begin(), maxHeap.end(), less<int>());maxHeap.pop_back();}minHeap.push_back(data);push_heap(minHeap.begin(), minHeap.end(), greater<int>());}}float GetMedium(){int num; //要输入数据个数int data; //每次存放数据vector<int> minHeap; //最小堆vector<int> maxHeap; //最大堆cin >> num;for (int i = 0; i < num; i++){cin >> data;InsertData(minHeap, maxHeap, data);}if (minHeap.size()>maxHeap.size()) return (float)minHeap[0];else if (minHeap.size() < maxHeap.size()) return (float)maxHeap[0];else return (minHeap[0] + maxHeap[0]) / (float)2;}int main(){float re = GetMedium();cout << re << endl;return 0;}
0 0
- 面试题71:数据流中的中位数
- 面试题64:数据流中的中位数
- 面试题64:数据流中的中位数
- 【面试题64】数据流中的中位数
- 面试题64. 数据流中的中位数
- 面试题64:数据流中的中位数
- 《剑指Offer》学习笔记--面试题64:数据流中的中位数
- 【剑指Offer学习】【面试题64:数据流中的中位数】
- 面试题_64——数据流中的中位数
- 剑指offer-面试题64:数据流中的中位数
- 《剑指offer》面试题64 数据流中的中位数
- 剑指offer--面试题64:数据流中的中位数
- 剑指offer-面试题64-数据流中的中位数
- 剑指offer 面试题64 数据流中的中位数
- 剑指offer面试题[64]-数据流中的中位数
- 【剑指Offer】面试题64:数据流中的中位数
- 剑指offer面试题64 数据流中的中位数(Java实现)
- 【剑指offer】面试题41:数据流的中位数
- Postgresql数据库的一些字符串操作函数
- VirtualBox虚拟机网络设置
- 第五周项目1-三角形类雏形(4)
- 在一台服务器上搭建多个项目的SVN
- Git的思想和基本工作原理
- 面试题71:数据流中的中位数
- 第五周,项目一,(1)三角形类雏形
- Linux定时器任务笔记
- 第五周项目3.1
- Android Activity的生命周期
- NoSQL数据库介绍(2)
- UDP丢包原因
- PCL系列——如何使用迭代最近点法(ICP)配准
- 第五周 结构体打印学生信息