Is Subsequence
Sana s ve t adında iki dize verilir. t dizgesinden bazı harfleri (hiç harf silmemek de mümkündür) silerek, kalan harflerin sırasını koruyup s dizgesini elde edebiliyorsan true, aksi takdirde false döndür. Örneğin, ace, abcde dizgesinin bir alt dizisidir, ancak aec değildir.
Fonksiyon
- sstring
- aranacak dize
- tstring
- harflerin silineceği dizge
- Döndürürboolean
- true, s dizisi t içinde aralarda boşluklar olabilecek şekilde sırayla okunabiliyorsa
Kısıtlar
1 ≤ s.length ≤ 3 × 1041 ≤ t.length ≤ 5 × 104svetyalnızca küçük İngilizce harfler içerir.
Örnekler
- Girdi
- s = "ace"t = "abcde"
- Çıktı
- true
- Açıklama
abcdeiçindenbvedöğelerini silin; geriye aynı sıraylaacekalır.
- Girdi
- s = "aec"t = "abcde"
- Çıktı
- false
- Açıklama
tüç harfin tamamını içerir, ancak tekc, teke'den önce gelir. 4. indekstekie'yi kullandıktan sonra sağında hiçckalmaz.
- Girdi
- s = "moon"t = "monsoon"
- Çıktı
- true
- Açıklama
monsoon'un 0. indeksindekim'yi, 1. ve 4. indekslerindekio'ları ve 6. indeksindekin'i kullanın. Aradaki harfler silinir.
Ek soru
t sabit kalıyorsa ve ona karşı bir milyon s dizgesini kontrol ediyorsan, her kontrolün t'nin tamamını okumaktan daha hızlı olması için t'yi nasıl hazırlardın?
İpuçları
Tek tek açın. Her biri biraz daha fazlasını gösterir.
sharfine bak.tiçindeki hangi kopyasını kullanmalısın?En erken kopyayı kullan. Daha sonraki bir kopyayı almak,
sdizisinin geri kalanı için yalnızca daha aztbırakabilir; bu nedenle en erken seçim asla daha kötü değildir.siçinde bir indeks,tiçinde de bir indeks tut.tboyunca her seferinde bir harf ilerle, her eşleşmedesiçindeki indeksi ilerlet ve sonundas’nin sonuna ulaşıp ulaşmadığını kontrol et.
Çözüm
Bir alt dizi, t içindeki harfleri herhangi bir yerde atlayabilir; bu da s için birçok yerleşim denemeyi düşündürür. Buna gerek yok: s içindeki her harfi yerleşebileceği en erken yerde eşleştirmek, başka herhangi bir seçimden asla daha kötü değildir; dolayısıyla iki işaretçiyle soldan sağa tek bir geçiş yeterlidir.
Önekler üzerinde dinamik programlama
Doğru, ama en büyük testlerde bitmiyor
Sezgi
dp[i][j], s dizgesinin ilk i harfinin t dizgesinin ilk j harfinin içine sığıp sığmadığını belirtir. t[j-1] olmadan zaten sığıyorsa ya da s[i-1], t[j-1] değerine eşitse ve ilk i-1 harf t[:j-1] içine sığıyorsa sığar. Boş önek her yere sığar ve i. satır yalnızca i-1. satırı okuduğundan, uzunluğu m+1 olan iki satır yeterlidir.
Tablo her hücreyi doldurur: 25.000 harfli s ve 50.000 harfli t için bu, 1.25 × 10^9 hücre demektir.
Algoritma
- Tüm değerleri
trueolanm+1değerlik birprevsatırı oluştur: boş birs,t'nin her önekine uyar. - 1'den
n'ye kadar heriiçin,cur[0] = falseolan bircursatırı oluştur. - 1'den
m'ye kadar herjiçin,cur[j]değerinicur[j-1]olarak ayarla veyas[i-1],t[j-1]'ye eşitseprev[j-1]olarak ayarla. prevdeğerinicurile değiştir.prev[m]değerini döndür.
def isSubsequence(s, t):
n, m = len(s), len(t)
# prev[j]: the first i-1 letters of s fit inside t[:j]. An empty s fits anywhere.
prev = [True] * (m + 1)
for i in range(1, n + 1):
cur = [False] * (m + 1)
for j in range(1, m + 1):
cur[j] = cur[j - 1] or (s[i - 1] == t[j - 1] and prev[j - 1])
prev = cur
return prev[m]İki işaretçiyle açgözlü eşleştirme
Sezgi
İhtiyacın olan bir sonraki s harfini gösteren bir i işaretçisi tut ve t içinde karşılaştığın ilk kopyasını al. Bu seçim güvenlidir. Geçerli bir yerleştirme s[i] harfinin daha sonraki bir kopyasını kullanıyorsa, en erken kopyayı onunla değiştirmek sırayı korur ve s'nin geri kalanı için t'nin daha büyük bir kısmını bırakır. Dolayısıyla herhangi bir yerleştirme varsa açgözlü yaklaşım onu bulur.
Döngü, t'nin her harfini en fazla bir kez okur ve iki dizin tutar: O(n + m) zaman ve O(1) bellek.
Algoritma
siçini = 0vetiçinj = 0ayarla.- Her iki dizinin indeksleri de dizelerinin içindeyken
s[i]ilet[j]değerlerini karşılaştır. - Eşitlerse
ideğerini artır. - Her durumda
jdeğerini artır. ideğerininsuzunluğuna eşit olup olmadığını döndür.
def isSubsequence(s, t):
i = j = 0
while i < len(s) and j < len(t):
if s[i] == t[j]:
i += 1
j += 1
return i == len(s)
Tuzaklar ve uç durumlar
siçindeki her harfi, önceki eşleşmeden sonra aramak yerinetiçinde herhangi bir yerde aramak. Bu,abcdeiçindeaecdizisinin kabul edilmesine yol açar.- Bir harfin tek bir kopyasını iki kez kullanmak.
noon,moondizisinin bir alt dizisi değildir: 3. indeksteki teknhem ilk hem de son harf olamaz. j'nint'nin sonuna ulaşıp ulaşmadığını döndürmek.sbulunmuş olsun ya da olmasın, döngü çoğu zaman orada sona erer; bunu yalnızcaigösterir.ttükendiğinde durmamak.abdizisiyle karşılaştırılanabc,falsedöndürmelidir.i,s'nin sonuna ulaştıktan sonras[i]değerini okumak. Python veya Java'da bu okuma hata verir; bu yüzden karşılaştırma yapmadan öncei'yi kontrol et.
Sıkça sorulan sorular3
Is Subsequence algoritmasının zaman karmaşıklığı nedir?
İki işaretçili çözüm, O(n + m) zamanda çalışır; burada n ve m, s ve t dizelerinin uzunluklarıdır ve fazladan O(1) bellek kullanır. Döngü en fazla m adımdan sonra durur. Önek tablosu O(n × m) zaman alır.
Is Subsequence, en uzun ortak alt diziyle nasıl ilişkilidir?
s, ancak en uzun ortak alt dizilerinin uzunluğu n, yani s'nin tamamı olduğunda t'nin bir alt dizisidir. İlk yaklaşımın önek tablosu, bu problem için oluşturduğunuz tablodur. Burada yalnızca s'nin tamamının sığıp sığmadığını bilmeniz gerekir; bu nedenle açgözlü geçiş yeterlidir.
Bir alt dizi ile bir alt dize arasındaki fark nedir?
Bir alt dize, art arda gelen harflerden oluşan bir bloktur; alt dizi ise sıra aynı kaldığı sürece harfleri atlayabilir. ace, abcde dizisinin bir alt dizisidir ancak alt dizesi değildir. Her alt dize bir alt dizidir, ancak bunun tersi geçerli değildir.
Benzer problemler
Aynı fikirleri kullanan problemler. İki üçünü çözmek bir kalıbı kalıcı hale getirir.
def isSubsequence(s, t):
# Kodu buraya yazınTest #1
Test #2
Test #3
Argümanlar
s = "ace" t = "abcde"
Beklenen Çıktı
true