Jewels and Stones
Sana harflerden oluşan iki dize verilir. jewels içindeki her harf bir mücevher türünü belirtir ve hiçbir harf tekrarlanmaz. stones içindeki her harf, sahip olduğun bir taşı temsil eder. Taşlarından kaçının mücevher olduğunu döndür. Harfler büyük/küçük harfe duyarlıdır: "a" ve "A" farklı türlerdir.
Fonksiyon
- jewelsstring
- mücevher sayılan taş türleri, her biri bir harf
- stonesstring
- sahip olduğun taşlar, her biri bir harf
- Döndürürinteger
- harfi mücevherlerde bulunan taşların sayısı
Kısıtlar
1 ≤ jewels.length ≤ 521 ≤ stones.length ≤ 104- Her iki dizge de yalnızca İngilizce harfler içerir; küçük ve büyük harfler.
jewelsharflerinin tümü birbirinden farklıdır.
Örnekler
- Girdi
- jewels = "rR"stones = "rubyRRr"
- Çıktı
- 4
- Açıklama
- Mücevher türleri
rveR'dir.rubyRRriçinder,R,Rvertaşları eşleşirkenu,bveyeşleşmez; bu nedenle cevap4'tür.
- Girdi
- jewels = "z"stones = "ZZZ"
- Çıktı
- 0
- Açıklama
- Tek mücevher türü küçük harfli
z’dir. Her taş büyük harfliZ’dir ve farklı bir türdür; bu yüzden hiçbiri sayılmaz.
Gönderirken +12 gizli test
İpuçları
Tek tek açın. Her biri biraz daha fazlasını gösterir.
Bir taş için, sayılıp sayılmayacağını hangi soru belirler?
Her taş için bir kez “bu harf bir mücevher mi?” diye soruyorsun. Bu soruyu sabit zamanda hangi veri yapısı yanıtlar?
jewelsharflerini bir kümeye koy, ardındanstonesüzerinde ilerleyip kümenin içerdiği her harfi say. Büyük-küçük harf durumunu olduğu gibi koru.
Çözüm
Her taş için bir yanıt gerekir: bu harf bir mücevher mi? Her taş için jewels dizgesinde arama yapmak aynı taramayı tekrar tekrar yapar. Mücevher harflerini bir kümeye bir kez ekle; böylece her taş için tek bir arama yeterli olur.
Her taş için mücevherleri tara
Sezgi
Taşları teker teker ele al. Her taş için jewels dizisini tara ve ona eşit olan ilk harfte dur. Eşleşme, sayaca 1 ekler. İlk örnekte u taşı r ve R ile karşılaştırılır, eşleşme bulunamaz ve sayaç artmaz.
İlk eşleşmede durabilirsin; çünkü mücevher harflerinin hepsi farklıdır, dolayısıyla bir taş en fazla biriyle eşleşebilir. Mücevher olmayan bir taşı ise bunu anlayana kadar tüm mücevher harfleriyle karşılaştırman gerekir.
j mücevher türü ve s taş için en fazla j × s karşılaştırma yapılır. Burada j ≤ 52, dolayısıyla 10^4 taş bile yaklaşık 5 × 10^5 karşılaştırmaya mal olur ve tarama zamanında tamamlanır. Tür listesinin büyümesiyle verimsizlik ortaya çıkar: aynı arama her taş için yeniden yapılır.
Algoritma
countdeğerini0olarak ayarla.- Her taş için, onu
jewelsdizgesindeki her harfle karşılaştır. - İlk eşleşen harfte,
countdeğerine1ekle ve sonraki taşa geç. countdeğerini döndür.
def numJewelsInStones(jewels, stones):
count = 0
for stone in stones:
for jewel in jewels:
if stone == jewel:
count += 1
break # the kinds are distinct: no second match is possible
return countMücevherleri bir kümeye koy
Sezgi
"Bu harf bir mücevher mi?" sorusunun yanıtı, aynı harf için her sorduğunda aynıdır. Bu yüzden her tür için bir kez yanıtla: jewels harflerinden bir küme oluştur. Küme, üyelik sorgularını sabit zamanda yanıtlar; böylece her taş için tarama yapmak yerine tek bir arama gerekir.
İlk örnekte küme {r, R} olur. rubyRRr üzerinde ilerlerken aramalar sırasıyla evet, hayır, hayır, hayır, evet, evet, evet yanıtını verir: dört mücevher. Kümeyi oluşturmak j adım, dizi boyunca ilerlemek s adım sürer; dolayısıyla toplam süre O(j + s) olur.
Küme en fazla 52 harf tutar. Yerleşik küme desteği olmayan bir dilde, karakter koduna göre indekslenmiş bir bayrak dizisi aynı işi görür.
Algoritma
jewelsiçindeki her harfi içeren bir küme oluştur.countdeğerini0olarak ayarla.- Her taş için, küme taşı içeriyorsa
countdeğerine1ekle. countdeğerini döndür.
def numJewelsInStones(jewels, stones):
kinds = set(jewels)
count = 0
for stone in stones:
if stone in kinds:
count += 1
return count
Tuzaklar ve uç durumlar
Algoritma tek bir döngüden oluşur. Yanlış yanıtlar, harflerin nasıl karşılaştırılıp sayıldığından kaynaklanır.
- Büyük-küçük harf farkını göz ardı etmek. Her iki dizenin de harflerini küçültmek,
zileZkarakterlerinin eşleşmesini sağlar ve ikinci örnek0yerine3döndürür. - Taşlar yerine farklı mücevher türlerini saymak.
rubyRRriki tür mücevher ama dört mücevher taşı içerir; tekrarlar da dahil olmak üzere her taş sayılır. - Kümeyi taş döngüsünün içinde oluşturmak. Her taş için yeniden oluşturmak, her seferinde
jadım gerektirir ve taramanınO(j × s)maliyetini geri getirir. Kümeyi döngüden önce, bir kez oluşturun. - Argümanların sırasını değiştirmek. Küme
jewelsdeğerini içermeli ve döngüstonesüzerinde ilerlemelidir. Roller ters çevrildiğinde ikinci örnek,ztüründeki tek mücevheri taşlarla karşılaştırıp yine0sonucunu verir; ancak("a", "aaa"),3yerine1döndürür.
Sıkça sorulan sorular3
Jewels and Stones'un zaman karmaşıklığı nedir?
Bir küme kullanıldığında karmaşıklık O(j + s) olur: jewels'tan kümeyi oluşturmak için j adım ve s taşın her biri için sabit zamanlı bir arama. Her taş için jewels'ı taramak O(j × s) karmaşıklığındadır.
Jewels and Stones için neden bir hash set kullanılır?
Her taş, harfinin bir mücevher olup olmadığını sorar. Bir hash kümesi bu soruyu sabit zamanda yanıtlar; jewels dizgesinde arama yapmaksa dizgenin uzunluğuyla orantılı zaman alır. Kümeyi oluşturmak için bir kez zaman harcarsın ve sonrasında her taşta zamandan tasarruf edersin.
Bunu bir küme kullanmadan çözebilir misin?
Evet. Harfler İngilizce harfleri olduğundan, karakter koduna göre indekslenen 128 veya 256 bayraklı bir dizi, hiç karma işlemi gerektirmeyen bir küme olarak çalışır. Her mücevher harfini işaretleyin, ardından bayrağı ayarlı olan taşları sayın. Ruby'deki stones.count(jewels) tüm işi tek bir çağrıda yapar, ancak bayrak dizisi arka planda neler olduğunu gösterir.
Benzer problemler
Aynı fikirleri kullanan problemler. İki üçünü çözmek bir kalıbı kalıcı hale getirir.
Python
def numJewelsInStones(jewels, stones):
# Kodu buraya yazınDurum 1
Durum 2
Girdi
jewels = "rR" stones = "rubyRRr"
Beklenen
4