给定两个整数K 、 X和一个由N 个不同元素组成的数组 arr[] ,任务是从给定数组中找到最接近第K个最小元素的 X 个元素。
例子:
Input: arr[] = {1, 2, 3, 4, 10}, K = 3, X = 2
Output: 2 3
Explanation: Kth smallest element present in the given array is 3 and X(= 2) closest array elements to 3 are {2, 3} or {3, 4}.
Therefore, the required output is 2 3.
Input: arr[] = {1, 9, 8, 2, 7, 3, 6, 4, 5, 10, 13, 12, 16, 14, 11, 15}, K = 3, X = 5
Output: 1 2 3 4 5
朴素的方法:解决这个问题的最简单的方法是使用双指针技术对数组进行排序并打印与给定数组的第K个最小元素最接近的X 个元素。
时间复杂度: O(N * log N)
辅助空间: O(1)
高效方法:为了优化上述方法,其思想是使用中值选择算法有效地计算给定数组的第 K个最小元素的值。请按照以下步骤解决问题:
- 使用中值选择算法计算给定数组的第 K 个最小值,比如KthElem。
- 初始化一个数组,比如diff[]来存储 arr[i]和KthElem的绝对差。
- 创建一个映射,比如说映射将数组的每个元素映射到当前元素和 KthElem的绝对差值。
- 遍历给定数组并将arr[i]附加到maps[abs(KthElem – arr[i])] 。
- 使用中值选择算法计算第X个最小元素,比如diff[]数组的 XthElem以精确打印 X 个最接近的项目。
- 最后,遍历diff[]数组并检查XthElem 是否小于或等于diff[i] 。如果发现为真,则在maps的帮助下打印数组的元素。
下面是上述方法的实现:
Python3
# Python3 program to implement
# the above approach
import collections
# Function to swap
# two elements of array
def swap(arr, a, b):
temp = arr[a]
arr[a] = arr[b]
arr[b] = temp
# Function to partition
# the array around x
def partition(arr, l, r, x):
# Traverse array
# from index l to r
for i in range(l, r):
# partition array
# around x
if arr[i] == x:
swap(arr, r, i)
break
x = arr[r]
i = l
# Traverse array
# from index l to r
for j in range(l, r):
if (arr[j] <= x):
swap(arr, i, j)
i += 1
swap(arr, i, r)
return i
# Function to find
# median of arr[]
# from index l to l + n
def findMedian(arr, l, n):
lis = []
for i in range(l, l + n):
lis.append(arr[i])
# Sort the array
lis.sort()
# Return middle element
return lis[n // 2]
# Function to get
# the kth smallest element
def kthSmallest(arr, l, r, k):
# If k is smaller than
# number of elements
# in array
if (k > 0 and
k <= r - l + 1):
# Stores count of
# elements in arr[l..r]
n = r - l + 1
# Divide arr[] in groups
# of size 5, calculate
# median of every group
# and store it in
# median[] array.
median = []
i = 0
while (i < n // 5):
median.append(
findMedian(arr,
l + i * 5, 5))
i += 1
# For last group with
# less than 5 elements
if (i * 5 < n):
median.append(
findMedian(arr,
l + i * 5, n % 5))
i += 1
# If median[] has
# only one element
if i == 1:
medOfMed = median[i - 1]
# Find median of all medians
# using recursive call.
else:
medOfMed = kthSmallest(
median, 0, i - 1, i // 2)
# Stores position of pivot
# element in sorted array
pos = partition(arr, l, r,
medOfMed)
# If position is same as k
if (pos - l == k - 1):
return arr[pos]
# If position is more,
if (pos - l > k - 1):
# recur for left subarray
return kthSmallest(arr, l,
pos - 1, k)
# Else recur for right subarray
return kthSmallest(arr, pos + 1,
r, k - pos + l - 1)
# If k is more than
# number of elements
# in the array
return 999999999999
# Function to print
def closestElements(arr, k, x):
# Stores size of arr
n = len(arr)
# Stores kth smallest
# of the given array
KthElem = kthSmallest(
arr, 0, n - 1, k)
# Store the value of
# abs(KthElem - arr[i])
diff = []
# Create a map to map
# array element to
# abs(KthElem - arr[i])
maps = collections.defaultdict(
list)
for elem in arr:
# Stres the value of
# abs(elem - KthElem)
temp = abs(elem - KthElem)
# map array elements
maps[temp].append(elem)
# append temp
diff.append(temp)
XthElem = kthSmallest(diff, 0,
n - 1, x)
# Store X closest elements
res = set()
# Traverse diff[] array
for dx in diff:
# If absolute difference is
# less than or eqaul to XthElem
if dx <= XthElem:
# Append closest elements
for elem in maps[dx]:
if len(res) < x:
res.add(elem)
return res
# Driver Code
if __name__ == '__main__':
arr = [1, 2, 3, 4, 10, 15]
k = 3
x = 2
# Store X closest elements
res = closestElements(arr, k, x)
# Print X closest elements
for i in res:
print(i, end =" ");
输出:
2 3
时间复杂度: O(N)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。