Dizilerin toplamını medyan bul
Uzunluğu iki sıralı dizilernverilen soru bulmak için, O süre içinden) zaman, Bir dizi her öğe ve dizinin her öğesi arasındaki tüm olası ikili toplamları B . içeren toplam sıralarını, medyan
Örneğin: [2,4,6] ve[1,3,5] B verilen iki dizi olsun.
Toplam dizi [2 1,2 3,2 5,4 1,4 3,4 5,6 1,6 3,6 5]
. O bu dizinin ortalama olarak bulacaksınn).
O soru çözme(n^2) düz ileri ama orada herhangi O güzel(nbu sorun için çözüm?
Not: Bu soruyu bir arkadaşım sordu ve görüşmeci O çözülebilir oldukça emindi röportaj(n) zaman.
CEVAP
Doğru O(n) çözümü oldukça karmaşıktır, ve metin, kod ve beceri önemli miktarda açıklamak ve kanıtlamak için alır. Daha doğrusu, detayları burada görülebilir http://www.cse.yorku.ca/~andy/pubs/X Y.pdf (yorum simonzack
) 3 sayfa yapmak çok inandırıcı bi şekilde alır.
Bu temelde bir akıllı böl-ve-fethet algoritması, diğer şeylerin yanısıra, alır avantajı aslında bu bir sıralanmış n-by-n matris, bir bulabildiğin O(n)
miktarı unsurları olan daha küçük/daha büyük bir sayı k
. Bu özyinelemeli olarak daha küçük submatrixes içine matrix tatili (tek satır ve sütunları, 7* *kolon olan bir submatrix sonuçlanan ve n/2
satır tek alarak) yukarıdaki adımı ile birlikte, O(n) O(n/2) O(n/4)... = O(2*n) = O(n)
bir karmaşıklık sonuçları. Çılgınca!
Bu kağıdı daha iyi açıklayamam, O(n logn)
daha basit bir çözüm yerine ben anlatacağım:) ediliyor.
O(n * logn) çözüm:
Bu bir söyleşi!Zamanında O(n)
çözüm elde edebilirsiniz. Peki neden uygun değil, ancak, O(n²)
diğer bariz adayları daha iyi yapabileceğini gösteren bir çözüm sunmak değil mi?
Verilen bir sayıdan daha küçük/büyük sayılar miktarını bulmak için O(n)
algoritma yukarıda bahsedilen kullanım n-by-n
sıralanmış bir matris içinde k
yapacağım. Gerçek bir matris ihtiyacımız yok unutmayın! Kartezyen toplam iki dizi boyutu n
şeklinde açıklanan OP sonuçlarında sıralanmış n-by-n
matrix, biz taklit ettiği dikkate alınarak elemanların dizi aşağıdaki gibi:
a[3] = {1, 5, 9};
b[3] = {4, 6, 8};
//a b:
{1 4, 1 6, 1 8,
5 4, 5 6, 5 8,
9 4, 9 6, 9 8}
Böylece her satır olmayan azalan sayılar içerir, her sütun. Şimdi, 19* *bir numara verilir gibi davran. Bu matris, sayıları çok fazla olan nasıl k
ve daha küçük nasıl O(n)
bulmak istiyoruz. Eğer her iki değer k
bizim ortanca demektir (n² 1)/2
daha az ise, açıkça!
Algoritma oldukça basittir:
int smaller_than_k(int k){
int x = 0, j = n-1;
for(int i = 0; i < n; i){
while(j >= 0 && k <= a[i] b[j]){
--j;
}
x = j 1;
}
return x;
}
Bu temelde birçok unsuru her satırda durumu nasıl uyum sayar. Satır ve sütunların zaten yukarıda da görüldüğü gibi sınıflandırılmaktadır beri, bu doğru sonucu verecektir. i
j
n
çoğu kez her yineleme olarak, algoritma O(n)
[j
for
döngü içinde sıfırlanır almaz unutmayın]. greater_than_k
algoritma benzer.
Şimdi, nasıl k
seçeriz? logn
parçasıdır.İkili Arama!/Yorumlar diğer yanıtlar belirtildiği gibi, medyan değer bu dizi içinde bulunmalıdır:
candidates[n] = {a[0] b[n-1], a[1] b[n-2],... a[n-1] b[0]};
.
Sadece bu dizi [de O(n*logn)
] sıralama ve ikili arama çalıştırın. Beri diziyi artık olmayan azaltılması amacıyla, düz ileri için fark tutarı sayılar daha küçük her candidate[i]
da olmayan bir azalan değeri (monoton fonksiyon), hangi yapar bunun için daha uygun bir ikili arama. smaller_than_k(k)
(n² 1)/2
daha küçük döndürür olan 37* *en büyük sayıyı ve cevap log(n)
tekrar elde edilir:
int b_search(){
int lo = 0, hi = n, mid, n2 = (n² 1)/2;
while(hi-lo > 1){
mid = (hi lo)/2;
if(smaller_than_k(candidate[mid]) < n2)
lo = mid;
else
hi = mid;
}
return candidate[lo]; // the median
}
Bir milyar sayıların medyan hesaplamak...
Nasıl sayı dizisi toplamını bulmak içi...
MySQL ile basit bir şekilde medyan hes...
"On-line" (yineleyici) istat...
Rolling medyan C algoritması...