Veri yapıları ve algoritmalardan en çok sorulan sorulardan biri, çoğunlukla telefon görüşmesi üzerine sorulmuştur.
Veri yapıları ve algoritmalardan en çok sorulan sorulardan biri, çoğunlukla telefon görüşmesi üzerine sorulmuştur.
Yanıtlar:
Hile yaparak ve aynı anda iki geçiş yaparak paralel olarak. Ancak işe alım yapanların bunu beğenip beğenmeyeceğini bilmiyorum.
Tek bir bağlantılı listede, güzel bir numara ile yapılabilir. İki işaretçi liste üzerinde hareket eder, biri çift hızlıdır. Hızlı olan sona ulaştığında, diğeri yarı yoldadır.
İki kez bağlı bir liste değilse, sadece bir liste sayabilir ve kullanabilirsiniz, ancak bu en kötü durumda belleğinizi iki katına çıkarmayı gerektirir ve liste bellekte saklamak için çok büyükse işe yaramaz.
Basit, neredeyse aptalca bir çözüm, her iki düğümde orta düğümü arttırmaktır
function middle(start) {
var middle = start
var nextnode = start
var do_increment = false;
while (nextnode.next != null) {
if (do_increment) {
middle = middle.next;
}
do_increment = !do_increment;
nextnode = nextnode.next;
}
return middle;
}
Hendrik'in cevabının detaylandırılması
İki kat bağlantılı bir listeyse, her iki uçtan yineleme yapın
function middle(start, end) {
do_advance_start = false;
while(start !== end && start && end) {
if (do_advance_start) {
start = start.next
}
else {
end = end.prev
}
do_advance_start = !do_advance_start
}
return (start === end) ? start : null;
}
verilmiş [1, 2, 3] => 2
1, 3
1, 2
2, 2
verilmiş [1, 2] => 1
1, 2
1, 1
verilmiş [1] => 1
verilmiş [] => null
Dizinin her öğesinin, baştan başlayarak listeden her bir düğüme çapraz sırada işaretçi olduğu dinamik bir dizi oluşturun. Ziyaret ettiğiniz kaç düğümü izleyen (her yeni bir düğüme her gittiğinizde artan) 1 olarak başlatılan bir tamsayı oluşturun. Sonuna geldiğinizde, listenin ne kadar büyük olduğunu bilirsiniz ve her bir düğüme sıralı bir işaretçi diziniz olur. Son olarak, listenin boyutunu 2'ye bölün (ve 0 tabanlı indeksleme için 1 çıkarın) ve dizinin o dizininde tutulan işaretçiyi getirin; listenin boyutu garip ise, hangi öğeyi döndüreceğinizi seçebilirsiniz (yine de ilkini döndüreceğim).
İşte (dinamik bir dizi fikri biraz sakat olsa bile) noktayı alan bazı Java kodu. C / C ++ sağlamak istiyorum ama bu alanda çok paslı.
public Node getMiddleNode(List<Node> nodes){
int size = 1;
//add code to dynamically increase size if at capacity after adding
Node[] pointers = new Node[10];
for (int i = 0; i < nodes.size(); i++){
//remember to dynamically allocate more space if needed
pointers[i] = nodes.get(i);
size++;
}
return pointers[(size - 1)/2];
}
Özyineleme birden fazla geçiş olarak kabul edilir mi?
Referansla bir tamsayı sayısı geçirerek listeyi sonuna kadar gezdirin. Daha sonra başvurmak üzere her düzeyde bu değerin yerel bir kopyasını oluşturun ve sonraki çağrıya giden ref sayımını artırın.
Son düğümde sayımı ikiye bölün ve sonucu kesin (yalnızca iki öğe olduğunda ilk düğümün "orta" olmasını istiyorsanız) veya yuvarlayın (ikinci düğümün olmasını istiyorsanız) orta"). Sıfır veya tek tabanlı bir dizini uygun şekilde kullanın.
Çözülüyorsa, ref sayısını yerel kopyayla (düğümün numarası olan) eşleştirin. Eşitse, bu düğümü döndürün; yoksa özyinelemeli çağrıdan döndürülen düğümü döndürür.
.
Bunu yapmanın başka yolları da var; bazıları daha az hantal olabilir (Birisi bir dizi içine okumak ve orta - kudos belirlemek için dizi uzunluğu kullanın dedi gördüm düşündüm). Ama açıkçası, iyi bir cevap yok, çünkü bu aptalca bir röportaj sorusu. Hala bağlantılı listeleri kullanan bir numara ( destekleyici görüş ); İkincisi, orta düğümü bulmak, gerçek hayat senaryolarında değeri olmayan keyfi, akademik bir alıştırmadır; Üç, orta düğümü gerçekten bilmem gerekirse, bağlantılı listem bir düğüm sayısını ortaya çıkaracaktır. Bu özelliği korumak, orta düğümü her istediğimde tüm listeyi dolaşarak zaman harcamaktan daha kolaydır. Ve son olarak, dört, her görüşmeci farklı cevapları beğenecek veya reddedecektir - bir görüşmecinin düşündüğü şey kaygan, diğeri gülünç diyecektir.
Röportaj sorularını neredeyse her zaman daha fazla soru ile cevaplıyorum. Eğer böyle bir soru alırsam (asla sahip değilim), soruyorum (1) Bu bağlantılı listede ne saklıyorsunuz ve gerçekten bir ihtiyaç varsa orta düğüme verimli bir şekilde erişmek için daha uygun bir yapı var mı? ; (2) Kısıtlarım nelerdir? Bellek bir sorun değilse (örneğin dizi yanıtı) daha hızlı yapabilirim, ancak görüşmeci hafızayı toplamanın israf olduğunu düşünürse, öleceğim. (3) Hangi dilde geliştireceğim? Bildiğim hemen hemen her modern dilde, listenin geçişini gereksiz kılan bağlantılı listelerle başa çıkmak için yerleşik sınıflar var - neden dilin geliştiricileri tarafından verimlilik için ayarlanmış bir şeyi yeniden icat ettiniz?
2 işaretçi kullanarak. Her yinelemede bir, her ikinci yinelemede bir artırın. 1. işaretçi bağlı listenin sonunu gösterdiğinde 2. işaretçi bağlı listenin orta modunu gösterecektir.