Given an array of integers size N, how can you efficiently find a subset of size K with elements that are closest to each other?
Le
This procedure can be done with O(N*K)
if A
is sorted. If A
is not sorted, then the time will be bounded by the sorting procedure.
This is based on 2 facts (relevant only when A
is ordered):
K
subsequent elements, the sum of distances can be calculated as the sum of each two subsequent elements time (K-i)*i
where i
is 1,...,K-1
.K
times the distance between the previously two smallest elements, and add K
times the distance of the two new largest elements. this fact is being used to calculate the closeness of a subset in O(1)
by using the closeness of the previous subset. Here's the pseudo-code
List FindClosestSubsets(int[] A, int K)
{
List minList = new List;
int minVal = infinity;
int tempSum;
int N = A.length;
for (int i = K - 1; i < N; i++)
{
tempSum = 0;
for (int j = i - K + 1; j <= i; j++)
tempSum += (K-i)*i * (A[i] - A[i-1]);
if (tempSum < minVal)
{
minVal = tempSum;
minList.clear();
minList.add(new pair(i-K, i);
}
else if (tempSum == minVal)
minList.add(new pair(i-K, i);
}
return minList;
}
This function will return a list of pairs of indexes representing the optimal solutions (the starting and ending index of each solution), it was implied in the question that you want to return all solutions of the minimal value.