![](/img/trans.png)
[英]Using binary search to find k-th largest number in n*m multiplication table
[英]What is the time complexity of using max heap to solve "Find the K-th largest number in the array" problem?
“找到数组中第 K 个最大的数”问题:
inputs: [3,2,1,5,6,4], k = 2
outputs: 5
inputs: [3,2,3,1,2,4,5,5,6], k = 4
outputs: 4
我知道这个问题可以通过quick select
和min heap
算法来解决。 但是,我在这里关注的是使用max heap
。 步骤如下:
1. Build max heap form the whole given array, inplace.
2. Iterate k times. In each iteration, Take and remove the heap top.
3. The last heap top taken at the k-th iteration is the result.
以下是cpp中的代码:
void swap(vector<int>& nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
void heapify_down(vector<int>& nums, int parent_idx, int end_idx) {
int left_idx = parent_idx * 2 + 1, right_idx = left_idx + 1;
while (left_idx <= end_idx) {
int largeset_idx = parent_idx;
if (nums[left_idx] > nums[largeset_idx]) largeset_idx = left_idx;
if (right_idx <= end_idx && nums[right_idx] > nums[largeset_idx]) largeset_idx = right_idx;
if (largeset_idx != parent_idx) {
swap(nums, parent_idx, largeset_idx);
parent_idx = largeset_idx;
left_idx = parent_idx * 2 + 1;
right_idx = left_idx + 1;
}
else {
return ;
}
}
}
void build_heap(vector<int>& nums) {
for (int i = nums.size() - 1; i >= 0; i--) heapify_down(nums, i, nums.size() - 1);
}
int findKthLargest(vector<int>& nums, int k) {
build_heap(nums);
int cnt = 0, res, cur_end = nums.size() - 1;
while (cnt != k) {
res = nums[0];
cnt += 1;
swap(nums, 0, cur_end);
cur_end -= 1;
heapify_down(nums, 0, cur_end);
}
return res;
}
这种方法的时间复杂度是多少? 我在第一步中使用自下而上的方法,这一步应该是 O(n)。 但是,while 循环让我感到困惑。 循环执行 k 次,每个循环都会调用heapify_down
,复杂度为 O(log(n))。 那么整体复杂度是O(n + k * log(n)) = O(max(n, k * log(n)))
吗? 如我错了请纠正我。
如果你做对了,构建一个堆是O(n)
并且移除顶部是O(log n)
并且k
未绑定它可能是n
。
所以总的来说它是O(n + k * log n) == O(n + n * log n) == O(n log n)
。
您没有更多信息,例如k < log n
之类的吗?
构建堆时不要使用heapify_down
,因为这会导致 O(n * log n)。 相反,如果堆的大小为奇数,则首先忽略最后一个元素。 然后从i = size / 2 - 1
开始并交换i
、 2 * i
和2 * i + 1
,因此最大的是i
。 重复直到i-- = 0
。 如果大小是奇数,则将最后一个元素添加到堆中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.