İki kuyruk kullanarak listeyi tersine çevirme


12

Bu soru, yığının her işlem için itfa edilmiş zamanında iki kuyruk kullanılarak simüle edilip edilemeyeceğine dair mevcut bir sorudan ilham alıyor . Cevap bilinmemektedir. İlk önce tüm PUSH işlemlerinin, ardından tüm POP işlemlerinin gerçekleştirildiği özel duruma karşılık gelen daha spesifik bir soru. Başlangıçta boş iki kuyruk kullanılarak bir öğesinin listesi ne kadar verimli bir şekilde ters çevrilebilir? Yasal işlemler:KO(1)N

  1. Bir sonraki öğeyi giriş listesinden (her iki kuyruğun kuyruğuna) daraltın.
  2. Her iki sıranın başındaki öğeyi dequeue edin ve yeniden sıralayın (her iki sıranın kuyruğuna).
  3. Her iki sıranın başındaki öğeyi ayıklayın ve çıktı listesine ekleyin.

Giriş listesi elemanlarından oluşuyorsa , tersine çevrilmiş çıktı listesini oluşturmak için gereken minimum işlem sayısı davranış? Orijinal soruyu olumsuz olarak çözeceği için den daha hızlı büyüdüğüne dair bir kanıt özellikle ilginç olacaktır.[ N , N - 1 , . . . , 2 , 1 ] O ( N )[1,2,...,N1,N][N,N1,...,2,1]O(N)


Güncelleme (15 Ocak 2011): Sorun , gönderilen cevaplarda ve yorumlarında gösterildiği gibi olarak çözülebilir ; ve nin alt sınırı önemsizdir. Bu sınırlardan herhangi biri geliştirilebilir mi?Ω ( N )O(NlogN)Ω(N)


Açıklığa kavuşturmak için: "her iki kuyruktaki son öğe" ile kuyruğun başındaki öğeye mi atıfta bulunuyorsunuz?
Peter Taylor

@Peter: Evet, açıklama için teşekkürler. Soruyu düzenledim.
mjqxxxx

Hem giriş hem de çıkış listesi yığınları mı? Eğer öyleyse, n op1s (aynı kuyruğa) ve ardından n op3s tersini yapar, değil mi? Bence önemli bir şey eksik olmalı.
32'de jbapple

@jbapple: Hayır, yığın değiller. Çıkış listesine öğeleri giriş listesinden okundukları sıraya göre yazmanız gerekir.
mjqxxxx

Yanıtlar:


11

N ikisinin gücü ise, tüm öğelerin kuyruklardan birinde başladığı ve kuyruklardan birinde ters sırada bitmesi gereken biraz daha sınırlı bir sorun için bile O (N log N) işlemlerinin yeterli olduğuna inanıyorum. giriş ve çıkış listeleri).

O (N) adımlarında, bir kuyruktaki tüm öğelerle başlamak, onları diğer kuyruktaki alternatif altkümelere bölmek için "biri sizin için bir tane" oynamak ve sonra bunları tekrar bir kuyrukta birleştirmek mümkündür. Maddelerin konumlarının ikili gösterimleri açısından, bu bir döndürme işlemi gerçekleştirir.

O (N) adımlarında, eleman çiftlerini bir kuyruktan çıkarmak, takas etmek, sonra geri koymak ve tüm çiftleri tersine çevirmek de mümkündür. Maddelerin konumlarının ikili gösterimleri açısından, bu konumun düşük dereceli bitini tamamlar.

O (log N) kez bir karışıklığı ve çiftli bir swap'ı tekrarlayarak, konumların ikili temsillerinin tüm bitlerini tamamlayabiliriz - ki bu listeyi tersine çevirmekle aynı şeydir.


Sonra listeyi bir ikili temsile bölebilir ve O (n lg n) algoritması için parça parça ters çevirebilirsiniz.
jbapple

İkili yerine 2-3 ağaç kullanarak tüm N'ye kadar uzanabileceğini düşünüyordum, ama belki de fikriniz daha basit. Fakat O (n log n) toplam adımlarında O (log n) parçalarının her birini nasıl tersine çevirirsiniz?
David Eppstein

İ için 0'dan [lg n] ye kadar O (toplam (2 ^ i) lg (2 ^ i)), Wolfram alfa'nın O (n lg n) olduğunu söylediği zaman : wolframalpha.com/input/?i=sum+ (2 ^ k) + log2 + (2 ^ k) + + 0 + 'dan + log2 + n'ye
jbapple

Elbette, her bir parçayı, uzunluğunun günlüğüne göre orantılı olarak tersine çevirebiliyorsanız, işleminiz tamamlanmıştır. Ancak parçaları tersine çevirdikten sonra bir yere koymanız gerekir ve bu, kalan parçaları tersine çevirmeyi zorlaştırabilir.
David Eppstein

Sorun bir "çıktı listesi" oluşturur. Onları oraya koyabilir miyiz?
4'te jbapple

1

Aklıma gelen en iyi algoritma , bir sıradan diğerine aktarımını gerektirir.i=0N/21(N2i2)

Mevcut iki kuyruğu sola ve sağa adlandırabilir İşte N'nin bile olduğu varsayımı ile bu algoritmanın temel fikri:

  1. İlk öğe listesinden değerleri okuyun ve tüm tek sayıları sol kuyruğa, çift sayıları sağ kuyruğa itin
  2. İlk adım olarak, maksimum değeri çıkarmanın en hızlı yolu, N / 2-1 öğelerini sağ kuyruktan sola aktarmak ve en üst değeri sağ kuyruktan çıkış listesine aktarmaktır.
  3. Şimdi başka bir kuyruk için de aynısını yapmalıyız - N / 2-1 öğelerini sol kuyruktan sağa aktarın ve üst öğeyi sol kuyruktan çıkış listesine aktarın
  4. Kuyrukları değiştirin ve N = N-2 için 2. ve 3. adımları tekrarlayın

Tek N için algoritmanın nasıl çalışması gerektiğini görmek kolaydır.


LaTeX-ish kodunu eklemek için $ ... $ kullanabilirsiniz (eksi \).
Mark Reitblatt
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.