Top View of Binary Tree
Yığın sıralamasında root dizisinde saklanan bir ikili ağaç alırsınız: kök 0 indeksinde, i indeksindeki düğümün çocukları 2*i+1 (sol) ve 2*i+2 (sağ) indekslerinde, boş bir konum içinse -1 bulunur.
Kök 0 sütunundadır; sol çocuk, ebeveyninin bir sütun solunda; sağ çocuk ise bir sütun sağında yer alır. Yukarıdan bakıldığında her sütundaki en sığ düğümü görürsünüz; eşitlik durumunda, seviyesinde soldan sağa ilk geleni (daha küçük indeksteki) görürsünüz. Gördüğünüz değerleri en soldaki sütundan en sağdakine doğru döndürün.
Fonksiyon
- rootinteger-array
- yığın düzenindeki ağaç, boş bir yer için -1 kullanarak
- Döndürürinteger-array
- her sütunda yukarıdan görülen değer, en soldaki sütundan başlayarak
Kısıtlar
1 ≤ root.length ≤ 32767- Her
root[i]değeri-1ya da0 ≤ root[i] ≤ 104koşulunu sağlayan bir değerdir ve hiçbir değer iki kez görünmez. root[0]hiçbir zaman-1değildir, dolayısıyla ağaçta en az bir düğüm vardır.- Dizi, son düğümden sonra fazladan
-1girdileriyle bitebilir. - Boş bir noktanın iki çocuğu da boştur ve ağaç en fazla
14seviyeye sahiptir.
Örnekler
- Girdi
- root = [5, 2, 9, 4, 7, 1, 6]
- Çıktı
- [4, 2, 5, 9, 6]
- Açıklama
- Soldan sağa sütunlarda
4(sütun -2),2(-1), kök5(0),9(1) ve6(2) bulunur.7ve1de 0. sütundadır, ancak kök onların üzerindedir.
- Girdi
- root = [1, 2, -1, -1, 3, -1, -1, -1, -1, -1, 4]
- Çıktı
- [2, 1, 4]
- Açıklama
2, -1. sütundadır. 4. indeksteki sağ çocuğu3, kökün altında yeniden 0. sütuna döner; bu yüzden gizlidir.3'ün sağ çocuğu olan 10. indeksteki4, 1. sütunda tek başınadır.
- Girdi
- root = [6, -1, -1]
- Çıktı
- [6]
- Açıklama
- 1 ve 2. indeksler
-1değerini içerir, bu nedenle60. sütunda tek başına durur ve görünümün tamamını oluşturur.
Ek soru
Dizi yerine düğüm nesneleri kullanıldığında, eşitliği bozmak için kullanılacak bir indeks yoktur. Eşitlik kuralını nasıl ifade edersin ve genişlik öncelikli arama kodun değişir mi?
İpuçları
Tek tek açın. Her biri biraz daha fazlasını gösterir.
Sütunları numaralandırın: kök 0'dır, sola doğru bir adım 1 çıkarır ve sağa doğru bir adım 1 ekler. Bir sütundaki hangi düğümü yukarıdan görebilirsiniz ve onu o sütundaki diğerlerinden nasıl ayırt edersiniz?
Düğümleri düzey düzey ve her düzeyin içinde soldan sağa ziyaret edersen, bir sütunun hangi düğümüyle ilk karşılaşırsın?
(indeks, sütun) çiftleri üzerinde, önce sol çocuğu, ardından sağ çocuğu ekleyerek genişlik öncelikli arama yapın. Bir değeri yalnızca bir sütun ilk kez göründüğünde kaydedin, en küçük ve en büyük sütunu takip edin ve sonunda sütunları sırayla okuyun.
Çözüm
Her sütun, en sığ düğümünü; eşitlik durumunda ise düzey sıralamasında ilk gelen düğümü gösterir. Bu, genişlik öncelikli aramanın düğümleri ziyaret ettiği sıranın aynısıdır; dolayısıyla aramanın bir sütunda karşılaştığı ilk düğüm yanıttır. Derinlik öncelikli dolaşım da işe yarar, ancak derinlikleri takip etmeli ve eşitlikleri dikkatle çözmelidir.
Derinlik öncelikli, her sütundaki en sığ düğüm
Sezgi
Ağacı derinlik öncelikli dolaşarak her düğümün sütununu ve derinliğini takip et; her sütun için şimdiye kadar bulunan en sığ düğümün derinliğini ve değerini tut.
Yalnızca daha küçük bir derinlikteyse değiştir. Derinlikleri eşit iki düğümden seviye sıralamasında önce gelenine, eşleşen sağ alt ağaçtan önce her sol alt ağacı gezen bir dolaşma önce ulaşır; çünkü iki yolun ayrıldığı yerde sola gider. Eşit derinlikte de değişiklik yapmak, sonraki düğümün kazanmasına yol açar: 3. indeks boşken 19 ve 23. indekslerde düğümler varsa, ikisi de -2 sütununda, 4. derinliktedir ve yanıt 19. indeksteki düğümdür.
Dolu sütunlar kesintisiz bir aralık oluşturur; çünkü -3 sütunundaki bir düğümün -1 ve -2 sütunlarında ataları vardır. Bu nedenle en küçük ve en büyük sütunu takip et. Her düğüm bir kez ziyaret edilir; zaman karmaşıklığı O(n) olur ve özyineleme yaklaşık h çağrı derinliğindedir.
Algoritma
- Kökü 0 sütunu ve 0 derinliğiyle ziyaret edin. Dizi sınırlarının dışındaki veya
-1değerini içeren bir indisten hemen dönün. - Sütunda henüz bir düğüm yoksa veya bu derinlik depolanmış derinlikten kesinlikle küçükse, bu derinliği ve değeri kaydedin.
2i+1değerinicol-1sütunuyla, ardından2i+2değerinicol+1sütunuyla bir seviye daha derinde ziyaret edin.- Depolanmış değerleri en küçük sütundan en büyük sütuna doğru döndürün.
def topView(root):
n = len(root)
best = {} # column -> (depth, value) of the shallowest node found so far
def visit(i, col, depth):
if i >= n or root[i] == -1:
return
# Replace only on a strictly smaller depth: on a tie, the node
# met first is the one further left, which comes first in level order.
if col not in best or depth < best[col][0]:
best[col] = (depth, root[i])
visit(2 * i + 1, col - 1, depth + 1)
visit(2 * i + 2, col + 1, depth + 1)
visit(0, 0, 0)
# The columns that hold a node form one unbroken range.
return [best[col][1] for col in range(min(best), max(best) + 1)]Genişlik öncelikli, sütun başına ilk düğüm
Sezgi
Kökü, ardından her düğümün sol çocuğunu ve sonra sağ çocuğunu alan bir kuyruk, düğümleri seviye sırasına göre çıkarır: d derinliğindeki her düğüm, d+1 derinliğindeki herhangi bir düğümden önce çıkarılır ve her seviyede soldan sağa ilerlenir. Problemin önceliği budur; bu nedenle bir sütunun aldığı ilk düğüm yukarıdan görülen düğümdür ve sonraki düğümlerin tümü atlanır.
Her düğüm için bir harita araması gerekir; toplam maliyet O(n)'dir. Kuyruk, tüm bir seviyeyi, yani düğümlerin yaklaşık yarısına kadarını tutabilir; dolayısıyla alan kullanımı O(n)'dir.
Algoritma
- (indeks 0, sütun 0) çiftini bir kuyruğa ekle.
- (
i,col) çiftini kuyruktan çıkar. Haritadacoliçin bir kayıt yoksa,root[i]değerini oraya kaydet. - Mevcut olan her çocuk için önce (
2i+1,col-1), ardından (2i+2,col+1) çiftini ekle. - Kuyruk boşaldığında, haritanın değerlerini en küçük sütundan en büyüğüne doğru döndür.
from collections import deque
def topView(root):
n = len(root)
top = {} # column -> value of the first node seen in that column
queue = deque([(0, 0)]) # (node index, column); the root is never empty
while queue:
i, col = queue.popleft()
# The queue hands out shallower nodes first, and left before right
# on one level, so the first node of a column is the one seen from above.
if col not in top:
top[col] = root[i]
left, right = 2 * i + 1, 2 * i + 2
if left < n and root[left] != -1:
queue.append((left, col - 1))
if right < n and root[right] != -1:
queue.append((right, col + 1))
# The columns that hold a node form one unbroken range.
return [top[col] for col in range(min(top), max(top) + 1)]
Tuzaklar ve uç durumlar
- Derinlik öncelikli dolaşımın bulduğu ilk düğümü tutmak. Kökün sol çocuğunun bir sağ çocuğu ve onun da bir sağ çocuğu varsa (sütun 1, derinlik 3), dolaşım bu düğümle kökün sağ çocuğundan (sütun 1, derinlik 1) önce karşılaşır.
- Önce sağ çocuğu kuyruğa eklemek: eşitlik durumunda yanlış düğüm seçilir.
- Sütunları metin olarak sıralamak:
"-1","-2"'den önce sıralanır. - Sol alt ağacın negatif sütunları doldurduğunu varsaymak. 2. örnekte
4düğümü kökün sol alt ağacında ve 1. sütundadır.
Sıkça sorulan sorular3
İkili ağacın üstten görünümü nedir?
Sütunları kökten başlayarak 0'dan numaralandırın; sol çocuk için bir eksiltin, sağ çocuk için bir artırın. Üstten görünüm, soldan sağa her sütun için köke en yakın düğümü listeler.
İkili ağacın üstten görünümünün zaman karmaşıklığı nedir?
Genişlik öncelikli arama, n düğümün her birini düğüm başına O(1) harita aramasıyla bir kez ziyaret eder; bu nedenle en küçük ve en büyük sütunu izlerseniz O(n) zamanda çalışır. Sütunlar için sıralı bir harita kullanıldığında, w sütun için karmaşıklık O(n log w) olur.
Üst görünüş, sol görünüşten ve alt görünüşten nasıl farklıdır?
Sol görünüm, her seviyenin ilk düğümünü seçer. Üst görünüm, her sütunun en sığ düğümünü seçer. Alt görünüm, sütun başına en derin düğümü seçer; bu nedenle bunun için yapılan bir genişlik öncelikli arama, her sütunda ilk düğümü tutmak yerine üzerine yazar.
Benzer problemler
Aynı fikirleri kullanan problemler. İki üçünü çözmek bir kalıbı kalıcı hale getirir.
def topView(root):
# Kodu buraya yazınTest #1
Test #2
Test #3
Argüman
root = [5, 2, 9, 4, 7, 1, 6]
Beklenen Çıktı
[4, 2, 5, 9, 6]