Baseball Game
Sıradışı bir oyunda puan tutuyorsun. operations listesini soldan sağa oku; her girdi bir puan kaydını değiştirir. "7" veya "-2" gibi bir tam sayı, o puanı ekler. "+" son iki puanın toplamını, "D" son puanın iki katını ekler ve "C" son puanı kalıcı olarak siler.
Son işlemden sonra kayıtta kalan puanların toplamını döndüren, calPoints adlı bir fonksiyon yaz. Boş bir kaydın toplamı 0 olur.
Fonksiyon
- operationsstring-array
- işlemler sırayla: metin olarak tam sayılar veya "+", "D", "C"
- Döndürürinteger
- sonunda kayıtta hâlâ bulunan puanların toplamı
Kısıtlar
1 ≤ operations.length ≤ 5000- Her bir girdi
"+","D","C"veya ondalık biçimde yazılmış,-3 × 104 ≤ value ≤ 3 × 104koşulunu sağlayan bir tam sayıdır. - Her işlem geçerlidir: kayıt en az iki puan içerdiğinde yalnızca
"+"gelir; en az bir puan içerdiğinde ise yalnızca"D"ve"C"gelir. - Kaydın içindeki her puan ve toplam, 32 bitlik işaretli bir tamsayıya sığar.
Örnekler
- Girdi
- operations = ["4", "-2", "D", "+", "C", "7"]
- Çıktı
- 5
- Açıklama
- Kayıt
[4, -2]olacak şekilde büyür,"D"-4ekler,"+"-2 + -4 = -6ekler,"C"bu-6değerini kaldırır ve son olarak7eklenir.[4, -2, -4, 7]kaydının toplamı5eder.
- Girdi
- operations = ["6", "D", "C", "C"]
- Çıktı
- 0
- Açıklama
"D",6'dan sonra12ekler; ardından iki"C"girdisi12ve6'yı kaldırır. Hiçbir şey kalmaz, bu yüzden cevap0'dır.
- Girdi
- operations = ["1", "2", "+", "+", "D"]
- Çıktı
- 21
- Açıklama
- İki
"+"girişi1 + 2 = 3ve ardından2 + 3 = 5işlemlerini yapar,"D"ise10ekler.[1, 2, 3, 5, 10]kaydının toplamı21eder.
Ek soru
En son "C" işlemini geri alıp iptal edilen puanı geri koyan bir işlemi O(1) zamanda nasıl eklersin?
İpuçları
Tek tek açın. Her biri biraz daha fazlasını gösterir.
Her kural en son puandan veya en son iki puandan bahseder.
"C"en son puanı kaldırdığında ne olmalı?Bir iptalden sonra, kaldırılan puandan önceki puan yeniden en son puan olur. Puanlar eklendikleri sıranın tersine çıkar; yığın da böyle çalışır.
Her yeni puanı yığına ekle: sayının kendisini,
"D"için en üsttekinin iki katını veya"+"için en üstteki iki sayının toplamını."C"için eleman çıkar. Sonunda geriye kalanların toplamını döndür ya da ekleme ve çıkarma yaparken bu toplamı güncel tut.
Çözüm
Her işlem en son puanları okur ve "C" bunları teker teker kaldırabilir; böylece daha eski puanlar yeniden en son puanlar olur. Bu, son giren ilk çıkar ilkesidir: her yeni puanı yığına ekle, "C" geldiğinde en üsttekini çıkar ve "D" ile "+" için en üstteki bir veya iki puanı oku.
Kaydı bir yığında oluşturun, sonunda toplayın
Sezgi
Kaydı, en yeni puan sonda olacak şekilde bir liste olarak tut; böylece her işlem yalnızca listenin sonunu etkiler. "C" işleminden sonra en yeni ikinci puan yeni en güncel puan olur ve daha sonra gelen "D" veya "+" işlemi bu puanı okumalıdır; listeden son elemanı çıkarmak onu görünür kılar. İlk örnekte "C", -6 değerini çıkarır ve geriye [4, -2, -4] kalır.
İşlemler bittiğinde listede tam olarak hesaba katılacak puanlar bulunur; bu yüzden bunları topla: O(n) zaman ve O(n) alan.
Algoritma
recordadlı boş bir yığınla başla."+"için, en üstteki iki girdinin toplamını yığına ekle."D"için, en üstteki girdinin iki katını yığına ekle."C"için, en üstteki girdiyi yığından çıkar.- Aksi hâlde girdi bir sayıdır: metni bir tam sayıya dönüştür ve yığına ekle.
- Yığında kalan her şeyin toplamını döndür.
def calPoints(operations):
record = [] # the scores that still count, newest last
for op in operations:
if op == "+":
record.append(record[-1] + record[-2])
elif op == "D":
record.append(2 * record[-1])
elif op == "C":
record.pop()
else:
record.append(int(op))
return sum(record)Çalışan toplamlı yığın
Sezgi
total değerini yığının toplamına eşit tut: her ekleme yeni puanı ekler ve her "C", yığından çıkardığı puanı çıkarır. Yığın kalmalı, çünkü iptal işleminin hangi puanı kaldıracağını bilmesi gerekir. İlk örnekte toplam 4, 2, -2, -8 şeklinde ilerler; iptal işlemi -6 değerini geri çıkararak toplamı -2 yapar ve 7 toplamı 5'e getirir.
Bu, O(n) zamanda tek geçişte yapılır ve işlemlerin herhangi bir önekinden sonra yanıt hazırdır. Her işlem kalıcı olan bir sayı olabileceğinden, alan kullanımı O(n)'dir.
Algoritma
- Boş bir
recordyığını vetotal = 0ile başla. "C"için en üstteki puanı çıkar vetotaldeğerinden çıkar.- Aksi hâlde yeni puanı hesapla:
"+"için en üstteki iki puanın toplamı,"D"için en üstteki puanın iki katı ya da sayının kendisi. - Yeni puanı yığına ekle ve
totaldeğerine ekle. totaldeğerini döndür.
def calPoints(operations):
record = [] # the scores that still count, newest last
total = 0 # always the sum of record
for op in operations:
if op == "C":
total -= record.pop() # the cancelled score leaves the total too
continue
if op == "+":
score = record[-1] + record[-2]
elif op == "D":
score = 2 * record[-1]
else:
score = int(op)
record.append(score)
total += score
return total
Tuzaklar ve uç durumlar
- Yalnızca toplamı ve son iki skoru tutmak.
["1", "2", "3", "C", "+"]içinde"+"için1ve2gerekir; iki skorlu bir pencerede ise1kaybolmuştur. - İptal edilen bir skoru toplamdan çıkarmamak. İkinci örnekte bu, toplamın
0yerine18olmasına yol açar. - Bir girdinin sayı olduğuna, bir rakam içerip içermediğini kontrol ederek karar vermek.
"-2"eksi işaretiyle başlar; üç sembolle karşılaştır ve geri kalan her şeyi dilin tamsayı ayrıştırıcısıyla ayrıştır. - Yanıtın pozitif olduğunu varsaymak.
["-3", "D"]toplamı-9eder.
Sıkça sorulan sorular3
Baseball Game'in zaman karmaşıklığı nedir?
Her işlem yığının tepesinde sabit miktarda iş yapar, bu nedenle n işlem O(n) zaman alır. İşlemlerin çoğu puan eklediğinde yığın O(n) alan kullanır.
Baseball Game için neden yığın doğru veri yapısıdır?
Her kural en son puanları okur veya kaldırır ve iptal işlemi, onun öncesindeki puanı ortaya çıkarır. Bu, son giren ilk çıkar düzenidir; bir yığın bunu O(1) push, pop ve peek işlemleriyle sağlar. Yalnızca sonundan yararlanılan bir dizi, yığın olarak iş görür.
Baseball Game O(1) ek alan kullanılarak çözülebilir mi?
Genel olarak hayır. Bir sayı dizisinin ardından gelen bir "C" girdileri dizisi, sayıları ters sırayla iptal eder; bu nedenle iptal edilip edilmeyeceklerini öğrenene kadar her sayıyı hatırlaman gerekir. En kötü durumda bu, O(n) bellek gerektirir.
Benzer problemler
Aynı fikirleri kullanan problemler. İki üçünü çözmek bir kalıbı kalıcı hale getirir.
def calPoints(operations):
# Kodu buraya yazınTest #1
Test #2
Test #3
Argüman
operations = ["4", "-2", "D", "+", "C", "7"]
Beklenen Çıktı
5