數字是不斷進入數組的,在每次添加一個新的數進入數組的同時返回當前新數組的中位數。
- 中位數是排序後數組的中間值,如果有數組中有n個數,則中位數爲A[(n-1)/2]。
- 比如:數組A=[1,2,3]的中位數是2,數組A=[1,19]的中位數是1。
持續進入數組的數的列表爲:[1, 2, 3, 4, 5],則返回[1, 1, 2, 2, 3]
持續進入數組的數的列表爲:[4, 5, 1, 3, 2, 6, 0],則返回 [4, 4, 4, 3, 3, 3, 3]
持續進入數組的數的列表爲:[2, 20, 100],則返回[2, 2, 20]
時間複雜度爲O(nlogn)
第一次用的插入排序,花了948ms。
後來改進爲兩個堆,一個最大堆儲存前一半數,一個最小堆儲存後一半數,插入次數是奇數時將值插入最大堆,是偶數時插入最小堆,同時保證最大堆的最大值小於最小堆的最小值。用時59ms。確實快了不少。順便寫了寫堆的插入刪除操作(堆下標從0開始)。
#include<iostream>
#include<vector>
using namespace std;
void insertmaxheap(vector<int> &maxheap, int tar)
{
int pos = maxheap.size();
maxheap.push_back(tar);
if(pos == 0)
return;
int child = pos;
int par = (pos-1)/2;
while(tar > maxheap[par] )
{
maxheap[child] = maxheap[par];
child = par;
if(par == 0)
break;
else
par = (par-1)/2;
}
maxheap[child] = tar;
}
int deletemaxheap(vector<int> &maxheap)
{
int ret = maxheap[0];
int pos = maxheap.size()-1;//新的size
int tar = maxheap[pos];
maxheap.pop_back();
if(pos == 0)
return ret;
else if(pos == 1)
{
maxheap[0] = tar;
return ret;
}
else if(pos == 2)
{
if(tar>maxheap[1])
{
maxheap[0] = tar;
}
else
{
maxheap[0] = maxheap[1];
maxheap[1] = tar;
}
return ret;
}
int par = 0;
int child = maxheap[1] < maxheap[2] ? 2 : 1;
while(tar < maxheap[child])
{
maxheap[par] = maxheap[child];
par = child;
if(2*child+1 < pos && 2*child+2>=pos)
child = 2*child+1;
else if(2*child+1 >= pos && 2*child+2>=pos)
break;
else
child = maxheap[2*child+1] < maxheap[2*child+2] ? 2*child+2 : 2*child+1;
}
maxheap[par] = tar;
return ret;
}
void insertminheap(vector<int> &minheap, int tar)
{
int pos = minheap.size();
minheap.push_back(tar);
if(pos == 0)
return;
int child = pos;
int par = (pos-1)/2;
while(tar < minheap[par] )
{
minheap[child] = minheap[par];
child = par;
if(par == 0)
break;
else
par = (par-1)/2;
}
minheap[child] = tar;
}
int deleteminheap(vector<int> &minheap)
{
int ret = minheap[0];
int pos = minheap.size()-1;//新的size
int tar = minheap[pos];
minheap.pop_back();
if(pos == 0)
return ret;
else if(pos == 1)
{
minheap[0] = tar;
return ret;
}
else if(pos == 2)
{
if(tar < minheap[1])
{
minheap[0] = tar;
}
else
{
minheap[0] = minheap[1];
minheap[1] = tar;
}
return ret;
}
int par = 0;
int child = minheap[1] > minheap[2] ? 2 : 1;
while(tar > minheap[child])
{
minheap[par] = minheap[child];
par = child;
if(2*child+1 < pos && 2*child+2>=pos)
child = 2*child+1;
else if(2*child+1 >= pos && 2*child+2>=pos)
break;
else
child = minheap[2*child+1] > minheap[2*child+2] ? 2*child+2 : 2*child+1;
}
minheap[par] = tar;
return ret;
}
vector<int> medianII(vector<int> &nums)
{
// write your code here
int m = nums.size();
if(m==0) return vector<int>(0);
/*
vector<int> vec(m, nums[0]);
//948ms
int i=0, j=0;
for(i=1; i<m; i++)
{
int temp = nums[i];
for(j=i; j>0 && temp<nums[j-1]; j--)
{
nums[j] = nums[j-1];
}
nums[j] = temp;
vec[i] = nums[i/2];
}
return vec;
*/
vector<int> maxheap;
vector<int> minheap;
vector<int> ret(m, 0);
for(int i=0; i<m; i++)
{
if(!(i&1))//ji ci
{
insertminheap(minheap, nums[i]);
int min = deleteminheap(minheap);
insertmaxheap(maxheap, min);
}
else// ou ci
{
insertmaxheap(maxheap, nums[i]);
int max = deletemaxheap(maxheap);
insertminheap(minheap, max);
}
ret[i] = maxheap[0];
}
return ret;
}
int main()
{
vector<int> vec = {1,2,3,4,5};
vector<int> ret(medianII(vec));
for(auto x:ret)
cout<<x<<" ";
cout<<endl;
}