通过从给定的 Array 中选择 K 个元素来最大化任何元素对之间的最小差异
给定一个由N个整数组成的数组,任务是从这N个元素中选择K个元素,使得每个 K 个数之间的最小差是最大的。返回 选择任意K个元素后的最大最小差值。
例子:
Input: N = 4, K = 3, arr = [2, 6, 2, 5]
Output: 1
Explanation: 3 elements out of 4 elements are to be selected with a minimum difference as large as possible. Selecting 2, 2, 5 will result in minimum difference as 0. Selecting 2, 5, 6 will result in minimum difference as 6-5=1
Input: N = 7, K = 4, arr = [1, 4, 9, 0, 2, 13, 3]
Output: 4
Explanation: Selecting 0, 4, 9, 13 will result in minimum difference of 4, which is the largest minimum difference possible
朴素方法:生成所有大小为 K 的子集并找到所有子集的最小差异。然后返回差异中的最大值。
有效的方法:给定的问题可以使用对答案技术的二分搜索来有效地解决。可以按照以下步骤解决问题:
- 按升序对数组进行排序
- 将最小答案ans初始化为 1
- 二进制搜索用于数组arr中从 1 到最大元素的范围
- 变量diff用于存储每次迭代时的最大最小差异
- 辅助函数用于检查是否可以选择K个元素,且最小差异大于先前迭代中计算的差异。如果可能,则返回 true,否则返回 false。
- 如果上述函数返回:
- True 然后将ans更新为dif并左更新为dif + 1
- False 然后将权限更新为差异- 1
下面是上述二分查找方法的实现
C++
// C++ implementation for the above approach
#include
using namespace std;
// To check if selection of K elements
// is possible such that difference
// between them is greater than dif
bool isPossibleToSelect(int arr[], int N,
int dif, int K)
{
// Selecting first element in the
// sorted array
int count = 1;
// prev is the previously selected
// element initially at index 0 as
// first element is already selected
int prev = arr[0];
// Check if selection of K-1 elements
// from array with a minimum
// difference of dif is possible
for (int i = 1; i < N; i++) {
// If the current element is
// atleast dif difference apart
// from the previously selected
// element then select the current
// element and increase the count
if (arr[i] >= (prev + dif)) {
count++;
// If selection of K elements
// with a min difference of dif
// is possible then return true
if (count == K)
return true;
// Prev will become current
// element for the next iteration
prev = arr[i];
}
}
// If selection of K elements with minimum
// difference of dif is not possible
// then return false
return false;
}
int binarySearch(int arr[], int left,
int right, int K, int N)
{
// Minimum largest difference
// possible is 1
int ans = 1;
while (left <= right) {
int dif = left + (right - left) / 2;
// Check if selection of K elements
// is possible with a minimum
// difference of dif
if (isPossibleToSelect(arr, N,
dif, K)) {
// If dif is greater than
// previous ans we update ans
ans = max(ans, dif);
// Continue to search for better
// answer. Try finding greater dif
left = dif + 1;
}
// K elements cannot be selected
else
right = dif - 1;
}
return ans;
}
// Driver code
int main()
{
int N, K;
N = 7, K = 4;
int arr[] = { 1, 4, 9, 0, 2, 13, 3 };
// arr should be in a sorted order
sort(arr, arr + N);
cout << binarySearch(arr, 0, arr[N - 1], K, N)
<< "\n";
return 0;
}
Java
// Java implementation for the above approach
import java.io.*;
import java.util.Arrays;
class GFG{
// To check if selection of K elements
// is possible such that difference
// between them is greater than dif
static boolean isPossibleToSelect(int []arr, int N,
int dif, int K)
{
// Selecting first element in the
// sorted array
int count = 1;
// prev is the previously selected
// element initially at index 0 as
// first element is already selected
int prev = arr[0];
// Check if selection of K-1 elements
// from array with a minimum
// difference of dif is possible
for (int i = 1; i < N; i++) {
// If the current element is
// atleast dif difference apart
// from the previously selected
// element then select the current
// element and increase the count
if (arr[i] >= (prev + dif)) {
count++;
// If selection of K elements
// with a min difference of dif
// is possible then return true
if (count == K)
return true;
// Prev will become current
// element for the next iteration
prev = arr[i];
}
}
// If selection of K elements with minimum
// difference of dif is not possible
// then return false
return false;
}
static int binarySearch(int []arr, int left,
int right, int K, int N)
{
// Minimum largest difference
// possible is 1
int ans = 1;
while (left <= right) {
int dif = left + (right - left) / 2;
// Check if selection of K elements
// is possible with a minimum
// difference of dif
if (isPossibleToSelect(arr, N,
dif, K)) {
// If dif is greater than
// previous ans we update ans
ans = Math.max(ans, dif);
// Continue to search for better
// answer. Try finding greater dif
left = dif + 1;
}
// K elements cannot be selected
else
right = dif - 1;
}
return ans;
}
// Driver code
public static void main(String[] args)
{
int N, K;
N = 7;
K = 4;
int []arr = { 1, 4, 9, 0, 2, 13, 3 };
// arr should be in a sorted order
Arrays.sort(arr);
System.out.println(binarySearch(arr, 0, arr[N - 1], K, N));
}
}
// This code is contributed by shivanisinghss2110
Python3
# Python 3 implementation for the above approach
# To check if selection of K elements
# is possible such that difference
# between them is greater than dif
def isPossibleToSelect(arr, N,
dif, K):
# Selecting first element in the
# sorted array
count = 1
# prev is the previously selected
# element initially at index 0 as
# first element is already selected
prev = arr[0]
# Check if selection of K-1 elements
# from array with a minimum
# difference of dif is possible
for i in range(1, N):
# If the current element is
# atleast dif difference apart
# from the previously selected
# element then select the current
# element and increase the count
if (arr[i] >= (prev + dif)):
count += 1
# If selection of K elements
# with a min difference of dif
# is possible then return true
if (count == K):
return True
# Prev will become current
# element for the next iteration
prev = arr[i]
# If selection of K elements with minimum
# difference of dif is not possible
# then return false
return False
def binarySearch(arr, left,
right, K, N):
# Minimum largest difference
# possible is 1
ans = 1
while (left <= right):
dif = left + (right - left) // 2
# Check if selection of K elements
# is possible with a minimum
# difference of dif
if (isPossibleToSelect(arr, N, dif, K)):
# If dif is greater than
# previous ans we update ans
ans = max(ans, dif)
# Continue to search for better
# answer. Try finding greater dif
left = dif + 1
# K elements cannot be selected
else:
right = dif - 1
return ans
# Driver code
if __name__ == "__main__":
N = 7
K = 4
arr = [1, 4, 9, 0, 2, 13, 3]
# arr should be in a sorted order
arr.sort()
print(binarySearch(arr, 0, arr[N - 1], K, N)
)
# This code is contributed by ukasp.
C#
// C# implementation for the above approach
using System;
using System.Collections.Generic;
class GFG{
// To check if selection of K elements
// is possible such that difference
// between them is greater than dif
static bool isPossibleToSelect(int []arr, int N,
int dif, int K)
{
// Selecting first element in the
// sorted array
int count = 1;
// prev is the previously selected
// element initially at index 0 as
// first element is already selected
int prev = arr[0];
// Check if selection of K-1 elements
// from array with a minimum
// difference of dif is possible
for (int i = 1; i < N; i++) {
// If the current element is
// atleast dif difference apart
// from the previously selected
// element then select the current
// element and increase the count
if (arr[i] >= (prev + dif)) {
count++;
// If selection of K elements
// with a min difference of dif
// is possible then return true
if (count == K)
return true;
// Prev will become current
// element for the next iteration
prev = arr[i];
}
}
// If selection of K elements with minimum
// difference of dif is not possible
// then return false
return false;
}
static int binarySearch(int []arr, int left,
int right, int K, int N)
{
// Minimum largest difference
// possible is 1
int ans = 1;
while (left <= right) {
int dif = left + (right - left) / 2;
// Check if selection of K elements
// is possible with a minimum
// difference of dif
if (isPossibleToSelect(arr, N,
dif, K)) {
// If dif is greater than
// previous ans we update ans
ans = Math.Max(ans, dif);
// Continue to search for better
// answer. Try finding greater dif
left = dif + 1;
}
// K elements cannot be selected
else
right = dif - 1;
}
return ans;
}
// Driver code
public static void Main()
{
int N, K;
N = 7;
K = 4;
int []arr = { 1, 4, 9, 0, 2, 13, 3 };
// arr should be in a sorted order
Array.Sort(arr);
Console.Write(binarySearch(arr, 0, arr[N - 1], K, N));
}
}
// This code is contributed by SURENDRA_GANGWAR.
Javascript
4
时间复杂度: O(N * log N)
空间复杂度: O(1)