小さなルートスタックのアイデアは:
まず根はk個の要素の最大値によって形成されたスタックのスタック要素の要素雨トップは、直接、積層素子の上面を返す場合、要素を追加するために比較した場合、スタック要素の以上トップ、削除した場合スタックノードの上部とスタックに要素を追加します。挿入や削除時間の複雑さはO(LOGN)です。
スタックの構築プロセスが複雑で、kは唯一のように比較スタックそのまま次建て必要性よりも大きい場合には、まず以下のk(K-1)より、初めて持つことになりますされ、初期およびNUMS配列サイズkとの関係を考慮する必要があります最初の原子炉を建設するための時間を追加します。
要素のスタックの最上部を除去する:最後の要素値をスタックするスタック要素値の順序の上部を(スタックテールは添字kは(アレイ1を開始添字)配列表現とヒープので、スタックの最上位は添字1である)、次いで上から下への規程。規程は、また、左右の息子(親ノード添字との関係N 2Nと2N + 1)非常に簡単であり、それはスタックの底に変化するまで、息子、次にスイッチを超える場合、サイズより。
添加元素:子ノードが親ノードである場合、ボトムアップ、比較(親ノードj / 2と比較して、子ノードj)の、すなわち親ノードから、次に、直接スタックに法律を要素を追加テールようになるまで変更する、以下の交換よりもヒープのトップ。
コード付き
#include <iostream>
#include <vector>
using namespace std;
class KthLargest
{
public:
int num;
int countnum=0;
vector<int> minHeap;
KthLargest(int k, vector<int>& nums)
{
num=k;
minHeap.resize(k+1);
minHeap[0]=-1;
int guodu;
int j; //j用来插入节点时维护堆
//如果初始化的数组大小小于要求的k项
if(nums.size()<=k)
{
for(int i=0;i<nums.size();i++)
{
j=i+1;
minHeap[j]=nums[i];
while (j/2 > 0 && minHeap[j] < minHeap[j/2])
{
// 自下往上堆化
guodu=minHeap[j/2];
minHeap[j/2]=minHeap[j];
minHeap[j]=guodu;
j = j/2;
}
countnum++;
}
}
//如果初始化的数组大小大于要求的k项
else
{
countnum=k;
//先建立一个k个元素的小根堆(用最大的k个元素)
for(int i=0;i<k;i++)
{
j=i+1;
minHeap[j]=nums[i];
while (j/2 > 0 && minHeap[j] < minHeap[j/2])
{
// 自下往上堆化
guodu=minHeap[j/2];
minHeap[j/2]=minHeap[j];
minHeap[j]=guodu;
j = j/2;
}
}
for(int i=0;i<nums.size()-k;i++)
{
if(nums[i+k]>=minHeap[1])
{
//删除顶点
minHeap[1]=minHeap[num];
int upToDown=1;
int minPos = upToDown;
while (true)
{
minPos = upToDown;
if (upToDown*2 <= num && minHeap[upToDown] > minHeap[upToDown*2])
minPos = upToDown*2;
if (upToDown*2+1 <= num && minHeap[minPos] > minHeap[upToDown*2+1])
minPos = upToDown*2+1;
if (minPos == upToDown)
break;
// swap(a, i, minPos);
guodu=minHeap[upToDown];
minHeap[upToDown]=minHeap[minPos];
minHeap[minPos]=guodu;
upToDown = minPos;
}
//插入新节点
minHeap[num]=nums[i+k];
j=num;
while (j/2 > 0 && minHeap[j] < minHeap[j/2])
{
// 自下往上堆化
guodu=minHeap[j/2];
minHeap[j/2]=minHeap[j];
minHeap[j]=guodu;
j = j/2;
}
}
}
}
}
int add(int val)
{
int guodu;
if(countnum<num)
{
countnum++;
int index=countnum;
minHeap[index]=val;
int j=index;
while (j/2 > 0 && minHeap[j] < minHeap[j/2])
{
// 自下往上堆化
guodu=minHeap[j/2];
minHeap[j/2]=minHeap[j];
minHeap[j]=guodu;
j = j/2;
}
return minHeap[1];
}
else
{
if(val<minHeap[1])
{
return minHeap[1];
}
else
{
//删除顶点
minHeap[1]=minHeap[num];
int i=1;
int minPos = i;
while (true)
{
minPos = i;
if (i*2 <= num && minHeap[i] > minHeap[i*2])
minPos = i*2;
if (i*2+1 <= num && minHeap[minPos] > minHeap[i*2+1])
minPos = i*2+1;
if (minPos == i)
break;
guodu=minHeap[i];
minHeap[i]=minHeap[minPos];
minHeap[minPos]=guodu;
i = minPos;
}
//插入新节点
minHeap[num]=val;
int j=num;
while (j/2 > 0 && minHeap[j] < minHeap[j/2])
{
// 自下往上堆化
guodu=minHeap[j/2];
minHeap[j/2]=minHeap[j];
minHeap[j]=guodu;
j = j/2;
}
return minHeap[1];
}
}
}
};
int main()
{
int k=3;
int val=3;
vector<int> nums;
nums.push_back(4);
nums.push_back(5);
KthLargest* obj = new KthLargest(k, nums);
cout<<obj->add(3)<<endl;
cout<<obj->add(5)<<endl;
cout<<obj->add(10)<<endl;
cout<<obj->add(9)<<endl;
cout<<obj->add(3)<<endl;
return 0;
}