文章目录
数据流中的第 K 大元素
设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。
请实现 KthLargest 类:
KthLargest(int k, int[] nums) 使用整数 k 和整数流 nums 初始化对象。
int add(int val) 将 val 插入数据流 nums 后,返回当前数据流中第 k 大的元素。
示例:
输入: [“KthLargest”, “add”, “add”, “add”, “add”, “add”] [[3, [4, 5, 8,2]], [3], [5], [10], [9], [4]]
输出: [null, 4, 5, 5, 8, 8]
解释:
KthLargest kthLargest = new KthLargest(3, [4, 5, 8, 2]);
kthLargest.add(3); // return 4 kthLargest.add(5); // return 5
kthLargest.add(10); // return 5 kthLargest.add(9); // return 8
kthLargest.add(4); // return 8
提示:
1 <= k <= 104 0 <= nums.length <= 104
-104 <= nums[i] <= 104
-104 <= val <= 104
最多调用 add 方法 104 次
题目数据保证,在查找第 k 大元素时,数组中至少有 k 个元素
题解(c++)
class KthLargest {
public:
priority_queue<int,vector<int>,greater<int>> pq;
int k;
KthLargest(int k, vector<int>& nums) {
this->k = k;
for(auto num:nums)
{
pq.push(num);
}
}
int add(int val)
{
pq.push(val);
while(pq.size() > k)
{
pq.pop();
}
return pq.top();
}
};
总结
一开始我采用快速排序,结果显示超时,后来发现其它人都是用优先级队列做的
错误示例(Java):
我个人认为超时的原因是因为在add方法中我利用for循环将nums数组复制到temp数组中,耗费了比较多的时间
class KthLargest {
private int k;
private int[] nums;
private static int[] leftArray;
public KthLargest(int k, int[] nums)
{
this.k = k;
this.nums = nums;
leftArray = new int[nums.length / 2];
}
public void swap(int index1, int index2, int[] array)
{
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
public int pivotIndex(int begin, int end, int[] array)
{
swap(begin, begin + (int) (Math.random() * (end - begin)), array);
//默认让第一个元素成为节点元素
int pivot = array[begin];
end--;
//快速排序
while(begin < end)
{
//从右向左扫描
while(begin < end)
{
//右边元素大于轴点元素
if(array[end] > pivot)
{
//右边元素索引左移
end--;
}
//右边元素小于轴点元素
else
{
array[begin++] = array[end];
break;
}
}
//从左向右扫描
while(begin < end)
{
//左边元素小于轴点元素
if(array[begin] < pivot)
{
begin++;
}
//左边元素>轴点元素
else
{
array[end--] = array[begin];
break;
}
}
}
//将备份元素放入原来的位置
array[begin] = pivot;
return begin;
}
//快速排序
public void sort(int begin, int end, int[] array)
{
//如果元素小于2,将中止快排
if (end - begin < 2)
{
return;
}
//确定轴点的位置
int mid = pivotIndex(begin, end, array);
sort(begin, mid, array);
sort(mid + 1, end, array);
}
public int add(int val)
{
int[] temp = new int[nums.length + 1];
temp[0] = val;
for(int index = 1;index < temp.length;index++)
{
temp[index] = nums[index - 1];
}
sort(0, temp.length,temp);
this.nums = temp;
return temp[temp.length - k];
}
}