SORU
15 Ocak 2010, Cuma


Bulma üç unsurun belirli bir sayıya en yakın olan bir dizi

Tamsayılar, bir dizi verilir1Bir2, ...,ndahil olmak üzere negatif ve pozitif, ve başka bir tamsayı S. Şimdi bulmamız gereken üç farklı tamsayı dizisinde, kimin toplamıdır en yakın verilen tamsayı S. Eğer var birden fazla çözüm, herhangi biri değil.

Tüm tamsayılar int32_t aralığı içinde kabul edilebilir ve aritmetik taşma toplamı hesaplama ile ortaya çıkar. Özel bir şey ama rastgele seçilmiş bir sayı.

Etkili bir algoritma arama kaba kuvvet dışında üç tamsayı bulmak vardır?

CEVAP
15 Ocak 2010, Cuma


Etkili bir algoritma arama kaba kuvvet dışında üç tamsayı bulmak vardır?

Evet; O bunu çözebiliriz(n2zaman! Bir ihtiyacını ortadan kaldıran ilk, senin sorunun P ifade edilmiş olabileceğini düşünün benzer biraz daha farklı bir şekilde "hedef değer":

orijinal sorun P:Toplamlar 7* *bir dizi n tam sayılar A verilen hedef değer ** 5, yok yok A 3-demet?

değiştirilmiş sorun P':Bir dizi verilen n A tamsayılar, var mı orada bir sıfır A toplamlar 3-demet?

Dikkat edin! bu sürüm sorunu P' P eksilterek S/3 her öğe A ama şimdi ihtiyacın yok hedef değer artık.

Eğer biz sadece tüm olası 3-dizilerini test açıkçası, eğer, O(n . sorunu çözmek istiyoruz ^sup>3bu kaba kuvvet, temel. Daha iyisini yapmak mümkün müdür? Eğer biraz daha akıllı bir şekilde dizilerini alırsak ne olur?

İlk olarak, bize O ilk penaltı maliyeti dizisi, (n günlük n) sıralamak için biraz zaman yatırım yapıyoruz. Şimdi bu algoritma idam edeceğiz:

for (i in 1..n-2) {
  j = i 1  // Start right after i.
  k = n    // Start at the end of the array.

  while (k >= j) {
    // We got a match! All done.
    if (A[i]   A[j]   A[k] == 0) return (A[i], A[j], A[k])

    // We didn't match. Let's try to get a little closer:
    //   If the sum was too big, decrement k.
    //   If the sum was too small, increment j.
    (A[i]   A[j]   A[k] > 0) ? k-- : j  
  }
  // When the while-loop finishes, j and k have passed each other and there's
  // no more useful combinations that we can try with this i.
}

Bu algoritma dizideki çeşitli noktalarda üç işaretçiler, i, j k yerleştirerek çalışır. i başında başlar ve yavaş yavaş sonuna kadar yolunda çalışır. k son eleman olduğunu gösteriyor. j i başladı nerede olduğunu gösteriyor. Biz yinelenen kendi göstergelere öğeleri toplamak için çalışın, ve her zaman aşağıdakilerden biri gerçekleşir:

  • Toplamı tam olarak doğru değil. Cevap bulduk.
  • Bu miktar çok küçük. j bir sonraki en büyük numarayı seçmek için sonuna kadar yaklaştırın.
  • Bu miktar çok büyüktü. k gelecek en küçük sayı seçmek için başlangıç için daha yakın bir yere taşıyın.

Her biri için* *25, j işaretçiler k giderek birbirlerine daha yakın olacak. Sonunda birbirlerine verirler ve bu noktada başka bir şey aynı öğeleri toplamak olurduk beri i,, sadece farklı bir sırayla denemeye gerek yok. Bu noktadan sonra, i gelecek ve tekrar deneyin.

Sonunda da yararlı olanakları egzoz edeceğiz, ya da çözüm bulacağız. Bu O olduğunu görebilirsiniz(n2dış döngü O(n ) infaz beri times ve iç döngü O(n) yürütme) kez. Mümkünse gerçekten fantezi almak varsa alt quadratically, bir bit gibi her tamsayı temsil ederek bu vektör ve hızlı Fourier dönüşümü gösteri yapmak, ama bu cevap kapsamı dışındadır.

Not:Bu bir soru olduğu için biraz hile yaptım buraya: bu algoritma aynı elemanın seçimi birden çok kez sağlar. O, (-1, -1, 2) geçerli bir çözüm olarak (0, 0, 0) olur. Ayrıca tek bulurkesincevap, başlık bahseder gibi yakın bir cevap değil. Bir egzersiz okuyucu, ararım seni anlamaya nasıl bir çalışma ile farklı elementler (ama bu çok basit bir değişiklik) ve tam cevaplar (ayrıca basit bir değişiklik).

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • EvilControllers

    EvilControll

    20 Ocak 2008
  • mipd1980

    mipd1980

    25 EKİM 2006
  • superflyy88

    superflyy88

    8 ŞUBAT 2009