给定一个大小为N的数组arr[]和一个整数K ,任务是在常量额外空间中从数组中找到第K个最小元素,并且该数组不能被修改。
例子:
Input: arr[] = {7, 10, 4, 3, 20, 15}, K = 3
Output: 7
Given array in sorted is {3, 4, 7, 10, 15, 20}
where 7 is the third smallest element.
Input: arr[] = {12, 3, 5, 7, 19}, K = 2
Output: 5
方法:首先我们从数组中找到最小和最大元素。然后我们设置low = min , high = max和mid = (low + high) / 2 。
现在,执行修改后的二分搜索,对于每个mid ,我们计算小于 mid且等于 mid的元素数。如果countLess < k并且countLess + countEqual ≥ k那么mid是我们的答案,否则我们必须修改我们的低和高。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the kth smallest
// element from the array
int kthSmallest(int* arr, int k, int n)
{
// Minimum and maximum element from the array
int low = *min_element(arr, arr + n);
int high = *max_element(arr, arr + n);
// Modified binary search
while (low <= high) {
int mid = low + (high - low) / 2;
// To store the count of elements from the array
// which are less than mid and
// the elements which are equal to mid
int countless = 0, countequal = 0;
for (int i = 0; i < n; ++i) {
if (arr[i] < mid)
++countless;
else if (arr[i] == mid)
++countequal;
}
// If mid is the kth smallest
if (countless < k
&& (countless + countequal) >= k) {
return mid;
}
// If the required element is less than mid
else if (countless >= k) {
high = mid - 1;
}
// If the required element is greater than mid
else if (countless < k
&& countless + countequal < k) {
low = mid + 1;
}
}
}
// Driver code
int main()
{
int arr[] = { 7, 10, 4, 3, 20, 15 };
int n = sizeof(arr) / sizeof(int);
int k = 3;
cout << kthSmallest(arr, k, n);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
// Function to return the kth smallest
// element from the array
static int kthSmallest(int[] arr, int k, int n)
{
// Minimum and maximum element from the array
int low = Arrays.stream(arr).min().getAsInt();
int high = Arrays.stream(arr).max().getAsInt();
// Modified binary search
while (low <= high)
{
int mid = low + (high - low) / 2;
// To store the count of elements from the array
// which are less than mid and
// the elements which are equal to mid
int countless = 0, countequal = 0;
for (int i = 0; i < n; ++i)
{
if (arr[i] < mid)
++countless;
else if (arr[i] == mid)
++countequal;
}
// If mid is the kth smallest
if (countless < k
&& (countless + countequal) >= k)
{
return mid;
}
// If the required element is less than mid
else if (countless >= k)
{
high = mid - 1;
}
// If the required element is greater than mid
else if (countless < k
&& countless + countequal < k)
{
low = mid + 1;
}
}
return Integer.MIN_VALUE;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 7, 10, 4, 3, 20, 15 };
int n = arr.length;
int k = 3;
System.out.println(kthSmallest(arr, k, n));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 implementation of the approach
# Function to return the kth smallest
# element from the array
def kthSmallest(arr, k, n) :
# Minimum and maximum element from the array
low = min(arr);
high = max(arr);
# Modified binary search
while (low <= high) :
mid = low + (high - low) // 2;
# To store the count of elements from the array
# which are less than mid and
# the elements which are equal to mid
countless = 0; countequal = 0;
for i in range(n) :
if (arr[i] < mid) :
countless += 1;
elif (arr[i] == mid) :
countequal += 1;
# If mid is the kth smallest
if (countless < k and (countless + countequal) >= k) :
return mid;
# If the required element is less than mid
elif (countless >= k) :
high = mid - 1;
# If the required element is greater than mid
elif (countless < k and countless + countequal < k) :
low = mid + 1;
# Driver code
if __name__ == "__main__" :
arr = [ 7, 10, 4, 3, 20, 15 ];
n = len(arr);
k = 3;
print(kthSmallest(arr, k, n));
# This code is contributed by AnkitRai01
C#
// C# implementation of the approach
using System;
using System.Linq;
class GFG
{
// Function to return the kth smallest
// element from the array
static int kthSmallest(int[] arr, int k, int n)
{
// Minimum and maximum element from the array
int low = arr.Min();
int high = arr.Max();
// Modified binary search
while (low <= high)
{
int mid = low + (high - low) / 2;
// To store the count of elements from the array
// which are less than mid and
// the elements which are equal to mid
int countless = 0, countequal = 0;
for (int i = 0; i < n; ++i)
{
if (arr[i] < mid)
++countless;
else if (arr[i] == mid)
++countequal;
}
// If mid is the kth smallest
if (countless < k
&& (countless + countequal) >= k)
{
return mid;
}
// If the required element is less than mid
else if (countless >= k)
{
high = mid - 1;
}
// If the required element is greater than mid
else if (countless < k
&& countless + countequal < k)
{
low = mid + 1;
}
}
return int.MinValue;
}
// Driver code
public static void Main(String[] args)
{
int []arr = { 7, 10, 4, 3, 20, 15 };
int n = arr.Length;
int k = 3;
Console.WriteLine(kthSmallest(arr, k, n));
}
}
// This code is contributed by Rajput-Ji
Javascript
输出:
7
时间复杂度: O(N log(Max – Min)) 其中 Max 和 Min 分别是数组中的最大和最小元素,N 是数组的大小。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。