Max Consecutive Ones
Her değeri 0 veya 1 olan bir nums dizisi alırsın. Bir seri, aralarında 0 olmadan yan yana duran 1'lerden oluşan bir dizidir. En uzun serinin uzunluğunu döndür; dizide hiç 1 yoksa 0 döndür.
Fonksiyon
- numsinteger-array
- 0'lardan ve 1'lerden oluşan bir dizi
- Döndürürinteger
- ardışık 1'lerden oluşan en uzun dizinin uzunluğu
Kısıtlar
1 ≤ nums.length ≤ 2 × 104- Her
nums[i]değeri0veya1'dir.
Örnekler
- Girdi
- nums = [1, 1, 0, 1, 1, 1, 0, 1]
- Çıktı
- 3
- Açıklama
- 1'ler üç ardışık dizi oluşturur:
0ile1arasındaki indeksler (uzunluk 2),3ile5arasındaki indeksler (uzunluk 3) ve tek başına7indeksi (uzunluk 1). En uzun dizinin uzunluğu3'tür.
- Girdi
- nums = [0, 1, 0, 1, 1]
- Çıktı
- 2
- Açıklama
- Diziler,
1indeksindeki tek1ve3ile4indekslerindeki çifttir.2uzunluğuyla çift kazanır.
- Girdi
- nums = [0, 0, 0]
- Çıktı
- 0
- Açıklama
- Hiçbir yerde 1 yok, dolayısıyla bir seri yok ve cevap
0.
Gönderirken +14 gizli test
Ek soru
Peki, en fazla k tane 0'ı 1'e çevirebilseydin ne olurdu? En uzun 1 dizisi ne kadar uzayabilir ve yine de bunu tek geçişte bulabilir misin?
İpuçları
Tek tek açın. Her biri biraz daha fazlasını gösterir.
Bir dizi 1, bir
0göründüğü anda sona erer. Daha önce geçtiğin değerler hakkında neyi hatırlaman gerekiyor?Yalnızca mevcut indekste sona eren dizinin uzunluğu önemlidir. 1 bunu bir artırır, 0 ise sıfıra sıfırlar.
Diziyi iki sayı ile bir kez dolaş: geçerli serinin uzunluğu ve şu ana kadarki en iyi uzunluk. Her 1'den sonra geçerli seriyi uzat ve en iyi uzunlukla karşılaştır; her 0'dan sonra geçerli seriyi sıfırla.
Çözüm
Bir çalışma, 0 göründüğü anda sona erer; bu nedenle herhangi bir indekste bilmeniz gereken tek şey, orada sona eren çalışmanın uzunluğudur. Her indekste baştan saymak, aynı işi tekrar tekrar yapar. 1 geldiğinde artan ve 0 geldiğinde sıfırlanan tek bir sayaç, soruyu tek geçişte yanıtlar.
Her indeksten ileri doğru say
Doğru, ama en büyük testlerde bitmiyor
Sezgi
Her çalışma bir yerden başlar. Bu yüzden başlangıç olarak her indeksi deneyin ve 1’leri görmeye devam ettiğiniz sürece ileri doğru ilerleyin; adım sayısı, orada başlayan dizinin uzunluğudur. Tüm başlangıçlar arasındaki en büyük sayı yanıttır. [1, 1, 0, 1, 1, 1, 0, 1] için 3 indeksindeki başlangıç, 6 indeksindeki 0 ile karşılaşmadan önce üç tane 1’in üzerinden geçer; bu da 3 sonucunu verir.
Yanıt doğrudur; çünkü en uzun dizi denediğiniz indekslerden birinde başlar ve ilk indeksinden itibaren yapılan ilerleme, dizinin uzunluğunu tam olarak ölçer.
Maliyet, örtüşmelerde gizlidir. n tane 1 içeren bir dizide, 0 indeksindeki başlangıç n adım, sonraki başlangıç n-1 adım ilerler ve bu böyle devam eder; toplamda yaklaşık n² / 2 adım atılır. n = 2 × 10^4 için bu 2 × 10^8 adımdır; yavaş dillerde zaman sınırı için bu çok fazladır.
Algoritma
best = 0olarak ayarla.- Her
startindeksi içinlength = 0olarak ayarla. start + lengthdizinin içindeyken venums[start + length]değeri1ikenlengthdeğerini 1 artır.bestvelengthdeğerlerinden büyük olanı sakla.bestdeğerini döndür.
def findMaxConsecutiveOnes(nums):
n = len(nums)
best = 0
for start in range(n):
length = 0
while start + length < n and nums[start + length] == 1:
length += 1
best = max(best, length)
return bestGeçerli bir sayaçla tek geçiş
Sezgi
Diziyi bir kez dolaş ve bulunduğun indeksin sonunda biten 1 dizisinin uzunluğunu tutmak için current değerini kullan. Bir 1 bu diziyi uzatır, bu yüzden current bir artar. Bir 0 diziyi bitirir, bu yüzden current yeniden 0 değerine düşer. Her 1'den sonra current ile best değerini karşılaştır.
[1, 1, 0, 1, 1, 1, 0, 1] dizisinde current sırasıyla 1, 2, 0, 1, 2, 3, 0, 1 değerlerini alır ve bunların en büyüğü 3 olur. Her dizi, son indeksinde ölçülür; bu noktada current dizinin tam uzunluğuna eşittir. Bu nedenle görülen en iyi değer, en uzun dizinin uzunluğudur.
Her değer bir kez okunur; bu da O(n) zaman demektir ve ihtiyacın olan tüm bellek iki tam sayıdan ibarettir.
Algoritma
best = 0vecurrent = 0değerlerini ayarla.numsiçindeki her değer için: değer1isecurrentdeğerini 1 artır vebestilecurrentdeğerlerinden büyük olanı koru.- Değer
0isecurrent = 0olarak ayarla. bestdeğerini döndür.
def findMaxConsecutiveOnes(nums):
best = 0
current = 0
for x in nums:
if x == 1:
current += 1
best = max(best, current)
else:
# A 0 breaks the run.
current = 0
return best
Tuzaklar ve uç durumlar
Tek geçişli sürüm kısadır; bu nedenle hatalar, yanıtı nerede güncellediğinizden kaynaklanır.
bestdeğerini yalnızca bir0ile karşılaştığınızda güncellemek. Dizinin sonuna ulaşan bir dizi,[0, 1, 1]örneğinde olduğu gibi, hiçbir zaman kaydedilmez. Her1'den sonra güncelleyin veya döngüden sonra bir kez daha karşılaştırın.- Bir
0ile karşılaştığınızdacurrentdeğerini sıfırlamayı unutmak; bu, ayrı dizilerdeki1değerlerini toplar ve[1, 1, 0, 1, 1]için4döndürür. bestdeğerini1veyanums[0]olarak başlatmak. Yalnızca0değerlerinden oluşan bir dizi0döndürmelidir.- Lua ve R'de dizinin indeksi
1'den başlar; bu nedenle ileri yöndeki geçişte< nyerinestart + length ≤ ndenetlenir.
Sıkça sorulan sorular4
En Fazla Ardışık 1'lerin zaman karmaşıklığı nedir?
Tek geçişli çözüm O(n) zamanda çalışır, çünkü her değeri tam olarak bir kez okur. O(1) ek alan kullanır: geçerli seri için bir sayaç ve en iyi seri için bir sayaç. Her indekste sayımı yeniden başlatmak, tamamı 1'lerden oluşan bir dizide O(n²) zaman alır.
Sayaç neden 1 yerine 0’a sıfırlanıyor?
Sayaç, geçerli dizinde sona eren 1’lerden oluşan dizinin uzunluğunu tutar. Geçerli değer 0 olduğunda, burada hiçbir 1 dizisi sona ermez; dolayısıyla uzunluğu 0 olur. Sonraki 1 ise değeri 1’e yükseltir; bu da yeni bir dizinin doğru uzunluğudur.
Bu bir kayan pencere problemi mi?
Bunu tek bir pencere olarak düşünebilirsin: pencere mevcut diziyi tutar, her değerde sağ kenar ilerler ve bir 0 sol kenarı onun ötesine taşır. Burada pencerenin adım adım küçülmesi gerekmez, bu yüzden tek bir sayaç iki kenarın yerini alır. Pencere yaklaşımı, en fazla k tane sıfırı bire çevirebildiğin daha zor sürümde işe yarar.
Bir tane 0'ı çevirebiliyorsan art arda gelen 1'leri nasıl sayarsın?
İki sayaç tut: burada biten, hiç bit değiştirilmemiş dizinin uzunluğu ve bir bit değiştirme hakkı zaten kullanılmış dizinin uzunluğu. 1 geldiğinde ikisi de bir artar. 0 geldiğinde, bit değiştirilmiş sayaç düz sayacın bir fazlası olur ve düz sayaç 0'a sıfırlanır. Yanıt, tek bir geçişte gördüğün en büyük bit değiştirilmiş sayaç değeridir.
Benzer problemler
Aynı fikirleri kullanan problemler. İki üçünü çözmek bir kalıbı kalıcı hale getirir.
Python
def findMaxConsecutiveOnes(nums):
# Kodu buraya yazınDurum 1
Durum 2
Durum 3
Girdi
nums = [1, 1, 0, 1, 1, 1, 0, 1]
Beklenen
3