I am trying to solve the "Kth Largest Element in an Array" problem on LeetCode. I have two different approaches that both theoretically have the same time complexity (O(n) on average), but only one of them passes the test cases while the other one times out. Here are the two approaches I have tried:
Approach 1: Quickselect (accepted)
int quickselect(int* nums, int l, int r, int k) {
if (l == r)
return nums[k];
int partition = nums[l], i = l - 1, j = r + 1;
while (i < j) {
do i++; while (nums[i] < partition);
do j--; while (nums[j] > partition);
if (i < j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}
if (k <= j) return quickselect(nums, l, j, k);
else return quickselect(nums, j + 1, r, k);
}
int findKthLargest(int* nums, int numsSize, int k) {
return quickselect(nums, 0, numsSize - 1, numsSize - k);
}
Approach 2: modified Quick Sort (time-out)
void q(int nums[], int left, int right, int k) {
if (left >= right) return;
int piv = nums[left]; // Select the first element as the pivot
int l = left, r = right;
while (l < r) {
// From right to left, find the first element less than the pivot
while (l < r && nums[r] <= piv) r--;
nums[l] = nums[r];
// From left to right, find the first element greater than the pivot
while (l < r && nums[l] >= piv) l++;
nums[r] = nums[l];
}
nums[l] = piv; // Place the pivot in the correct position
if (l == k) return; // Found the kth element
if (l < k) q(nums, l + 1, right, k); // Search the right side
else q(nums, left, l - 1, k); // Search the left side
}
int findKthLargest(int* nums, int numsSize, int k) {
q(nums, 0, numsSize - 1, k - 1); // We use k - 1 because the array is 0-indexed
return nums[k - 1]; // Return the kth largest element
}
Problem:
Time Complexity: Both algorithms should have an average time complexity of O(n).
Why it works for Approach 1: The first approach, which is a standard quickselect implementation, passes the test cases successfully on LeetCode.
Why it doesn't work for Approach 2: The second approach, despite having the same time complexity, is timing out for large test cases.
q()'s inner loops onnums[r(l)] < piv. (Find out how this makes a difference with repeated values.)