Varsayım: Biz A k değerlerine önem medyanın en yakınları. Eğer bir A = {1,2,2,2,2,2,2,2,2,2,2,2,3} ve k = 3 olsaydı, cevap {2,2,2}. Benzer şekilde A = {0,1,2,3,3,4,5,6}, k = 3 ise, {2,3,3} ve {3,3,4} cevapları eşit olarak geçerlidir. Dahası, bu değerlerin geldiği endekslerle ilgilenmiyoruz, ancak algoritmanın işe yarayacağı küçük ufak tefek şeyler hayal ediyorum.
- olarak Grodrigues durumları, ilk O (n) zamanda orta değerlerini bulmak. Biz varken, en büyük ve en küçük sayıyı takip edin
- Sonraki, K, k öğeleri uzun bir dizi oluşturun. Bu dizi, bir maddenin medyandan uzaklığını içerecektir.(A [i] ise her öğe için K.
- içine bir ilk k ürün A [i] [i] ortanca K. her öğeye A'nın mesafeyi karşılaştırmak
- kopyala unutmayın medyandan K'ye en uzak olandan daha yakın olana, o maddeyi değiştirir.Bir optimizasyon olarak, K'nın en yakın ve en uzak öğelerini de ortanca izleyebiliriz, bu yüzden K ile daha hızlı bir karşılaştırma yapabiliriz veya K dizisini tutabiliriz ama ne optimizasyon O (n) zaman içinde çalıştırmak için gerekli olan
Pseudocode C++ imsi.
/* n = length of array
* array = A, given in the problem
* result is a pre-allocated array where the result will be placed
* k is the length of result
*
* returns
* 0 for success
* -1 for invalid input
* 1 for other errors
*
* Implementation note: optimizations are skipped.
*/
#define SUCCESS 0
#define INVALID_INPUT -1
#define ERROR 1
void find_k_closest(int n, int[] array, int k, int[] result)
{
// if we're looking for more results than possible,
// it's impossible to give a valid result.
if(k > n) return INVALID_INPUT;
// populate result with the first k elements of array.
for(int i=0; i<k; i++)
{
result[i] = array[i];
}
// if we're looking for n items of an n length array,
// we don't need to do any comparisons
// Up to this point, function is O(k). Worst case, k==n,
// and we're O(n)
if(k==n) return 0;
// Assume an O(n) median function
// Note that we don't bother finding the median if there's an
// error or if the output is the input.
int median = median(array);
// Convert the result array to be distance, not
// actual numbers
for(int i=0; i<k; i++)
{
result[i] = result[i]-median;
// if array[i]=1, median=3, array[i] will be set to 2.
// 4 3 -1.
}
// Up to this point, function is O(2k+n) = O(n)
// find the closest items.
// Outer loop is O(n * order_inner_loop)
// Inner loop is O(k)
// Thus outer loop is O(2k*n) = O(n)
// Note that we start at k, since the first k elements
// of array are already in result.
OUTER: for(int i=k; i<n; i++)
{
int distance = array[i]-median;
int abs_distance = abs(distance);
// find the result farthest from the median
int idx = 0;
#define FURTHER(a,b) ((abs(a)>abs(b)) ? 1 : 0;
INNER: for(int i=1; i<k; i++)
{
idx = (FURTHER(result[i],result[i-1])) ? i:i-1;
}
// If array[i] is closer to the median than the farthest element of
// result, replace the farthest element of result with array[i]
if(abs_distance < result[idx]){ result[idx] = distance; }
}
}
// Up to this point, function is O(2n)
// convert result from distance to values
for(int i=0; i<k; i++)
{
result[i] = median - result[i];
// if array[i]=2 , median=3, array[i] will be set to 1.
// -1 3 4.
}
}
IMO sen listeyi sıralamak zorunda kalacak ve bu her zaman O (n) 'den büyük olacaktır. – leppie
Sorununuz, O (n) saatinde rasgele persentil bulabilmekle eşdeğerdir. ** sadece ** O (n) zamanındaki medyanı bulmak (yani probleminizi k = 1 için çözmek) mümkündür ancak önemsiz değildir. Algoritma muhtemelen yüzdelerini bulmak için genişletilebilir. Niçin buna ihtiyacın var? Ödev mi? –
Dup: http://stackoverflow.com/questions/1557678/how-to-find-k-nearest-neighbors-to-the-median-of-n-distinct-numbers-in-on-time? – dfens