Contains Duplicate
Bir tamsayı dizisi nums alırsın. Herhangi bir değer en az iki kez görünüyorsa true, tüm değerler farklıysa false döndür.
Fonksiyon
- numsinteger-array
- kontrol edilecek tam sayılar
- Döndürürboolean
- herhangi bir değer en az iki kez görünüyorsa true, aksi takdirde false
Kısıtlar
1 ≤ nums.length ≤ 104-109 ≤ nums[i] ≤ 109
Örnekler
- Girdi
- nums = [3, 1, 4, 1, 5]
- Çıktı
- true
- Açıklama
1değeri 1. indekste ve tekrar 3. indekste görünür, bu nedenle cevaptrueolur.
- Girdi
- nums = [2, 7, 1, 8]
- Çıktı
- false
- Açıklama
2,7,1ve8dört farklı değerdir, bu yüzden hiçbir değer tekrarlanmaz.
- Girdi
- nums = [-4, 4, 0]
- Çıktı
- false
- Açıklama
-4ve4aynı mutlak değere sahiptir ancak farklı sayılardır ve0bir kez görünür, bu yüzden yanıtfalseolur.
Gönderirken +17 gizli test
Ek soru
Dizinin tamamını her zaman okumak yerine, ilk tekrarlanan değerle karşılaşır karşılaşmaz durabilir misin?
İpuçları
Tek tek açın. Her biri biraz daha fazlasını gösterir.
Her değeri diğer tüm değerlerle karşılaştırmak işe yarar, ancak
10^4değer için bu yaklaşık5 × 10^7karşılaştırma demektir. Daha önce geçtiğin değerlerle ilgili neyi hatırlayabilirsin?Tekrar, mevcut değerin daha önce karşılaştığınız bir değer olduğu anlamına gelir. Bir hash kümesi, ortalama sabit zamanda "bu değerle daha önce karşılaştım mı?" sorusunu yanıtlar.
Diziyi boş bir kümeyle bir kez dolaş. Her değer için, kümede zaten varsa
truedöndür; yoksa kümeye ekle. Döngü biterse tüm değerler farklıdır.
Çözüm
Tekrar, daha önce karşılaştığınız bir değerdir ve işin özü, “bununla daha önce karşılaştım mı?” sorusunu hızlıca yanıtlamaktır. Her çifti karşılaştırmak bu soruyu yanıtlar, ancak n = 10^4 için bu, yaklaşık 5 × 10^7 karşılaştırma demektir: n(n-1)/2. Sıralama, eşit değerleri yan yana getirir ve bir hash kümesi soruyu ortalama olarak O(1) zamanda yanıtlar; böylece tek bir geçiş yeterli olur.
Sırala, ardından komşuları karşılaştır
Sezgi
Sıralanmış bir dizide eşit değerler yan yana gelir. [3, 1, 4, 1, 5], [1, 1, 3, 4, 5] şeklinde sıralanır ve iki 1 artık yan yanadır. Bu yüzden sıralamadan sonra her değeri yalnızca hemen önündeki değerle karşılaştırırsın: her çifti denemek için gereken n(n-1)/2 karşılaştırma yerine n-1 karşılaştırma.
Hiçbir komşu eşit değilse, hiçbir yerdeki iki değer de eşit değildir: sıralı düzende x'in iki kopyası arasında yer alan herhangi bir değer hem en az x hem de en fazla x olmak zorundadır; dolayısıyla o da başka bir x olur.
Sıralama işlemi O(n log n) zaman karmaşıklığına hâkimdir. nums dizisini yerinde sıralamak ek bir dizi gerektirmez, ancak çağıranın girdisinin sırasını değiştirir; buna izin verilmiyorsa O(n) alan maliyeti olan bir kopyayı sırala.
Algoritma
numsdizisini artan sırada sırala.ideğerini 1'den son indekse kadar döngüye sok.nums[i],nums[i-1]değerine eşitsetruedöndür.- Döngüden sonra
falsedöndür.
def containsDuplicate(nums):
nums.sort()
# After sorting, equal values sit next to each other.
for i in range(1, len(nums)):
if nums[i] == nums[i - 1]:
return True
return FalseBir hash kümesiyle tek geçiş
Sezgi
Diziyi bir kez dolaşın ve üzerinden geçtiğiniz her değeri bir karma kümesinde tutun. Bir değer eklemeden önce, kümede zaten olup olmadığını kontrol edin. [3, 1, 4, 1, 5] için küme {3, 1, 4} hâline gelir ve ikinci 1 geldiğinde küme bu değeri zaten içerir; bu yüzden 5 değerini okumadan true döndürürsünüz.
Küme her zaman geçerli konumdan önceki değerleri tam olarak içerir; dolayısıyla eşleşme, geçerli değerin daha önce göründüğü anlamına gelir. Eşleşme olmadan sona ulaşmak ise tüm değerlerin birbirinden farklı olduğu anlamına gelir.
Karma kümesinde arama ve ekleme, ortalama olarak O(1) zaman alır; bu nedenle tüm geçiş O(n) sürer. Bunun bedeli bellektir: tekrar yoksa küme, sonunda n değerin tümünü içerir.
Algoritma
- Boş bir hash kümesi
seenoluştur. numsiçindeki her değer için, değerseeniçindeysetruedöndür.- Aksi takdirde onu
seenkümesine ekle. - Döngüden sonra
falsedöndür.
def containsDuplicate(nums):
seen = set()
for num in nums:
if num in seen:
return True
seen.add(num)
return False
Tuzaklar ve uç durumlar
Mantık kısa, bu yüzden hatalar döngü sınırlarında ve neyi karşılaştırdığınızda gizlidir.
- İç döngüyü
j = inoktasından başlatarak her çifti karşılaştırmak. Böylece her değer kendisiyle eşleşir ve yanıt her zamantrueolur. - Önce sıralamadan komşuları karşılaştırmak.
[9, 1, 2, 3, 9]dizisindeki iki9yan yana değildir. - Komşu döngüsünü 0 indeksinden başlatıp
nums[-1]değerini okumak. 1’den başlayın; tek değerli bir dizi doğru şekildefalsedöndürür. - Mutlak değerleri aynı olan değerleri eşit kabul etmek; örneğin
abs(x)değerinin özetini almak.-4ve4farklı sayılardır. x - ydöndüren bir C sıralama karşılaştırıcısı yazmak. Burada fark±2 × 10^9sınırları içinde kalır; bu daintsınırı olan2^31-1 = 2147483647değerinin altındadır, dolayısıyla bu durumda sığar. Ancakintsınırlarına yakın değerlerde taşmaya neden olur ve sıralama yanlış sonuç verir. Bunun yerine(x > y) - (x < y)döndürün.
Sıkça sorulan sorular4
Contains Duplicate'ın zaman karmaşıklığı nedir?
Küme (hash set) çözümü ortalama olarak O(n) zamanda çalışır ve O(n) ek alan kullanır. Önce sıralamak O(n log n) zaman alır ve girdiyi yeniden sıralayabiliyorsanız ek dizi gerektirmez. Her çifti karşılaştırmak O(n²) zaman alır.
Ekstra alan kullanmadan Contains Duplicate problemini çözebilir misin?
Evet, diziyi yeniden sıralamanıza izin veriliyorsa: diziyi yerinde sıralayın ve her değeri komşusuyla karşılaştırın. Böylece O(n) küme yerine O(n log n) zaman kullanılır. Yeniden sıralama yapmadan ve ek bellek kullanmadan geriye kalan tek seçenek O(n²) ikili kontroldür.
Bir hash kümesi kontrolü neden hızlı yapar?
Bir karma kümesi değerleri karmalarına göre saklar; bu nedenle bir değeri içerip içermediğini sormak, tarama yapmak yerine ortalama olarak sabit zaman alır. Her öğe için bir arama ve bir ekleme işlemi gerekir; bu da tüm geçişi doğrusal zamanlı hâle getirir.
Küme boyutunu dizi uzunluğuyla karşılaştırmak geçerli bir çözüm müdür?
Evet. nums dizisinin tamamından bir küme oluşturup bunun diziden daha küçük olup olmadığını kontrol etmek, O(n) zamanında doğru yanıtı verir. Döngü sürümü genellikle daha iyidir çünkü ilk tekrarla karşılaştığı anda sonucu döndürür; tüm kümeyi oluşturmak ise her zaman her değeri okur.
Benzer problemler
Aynı fikirleri kullanan problemler. İki üçünü çözmek bir kalıbı kalıcı hale getirir.
Python
def containsDuplicate(nums):
# Kodu buraya yazınDurum 1
Durum 2
Durum 3
Girdi
nums = [3, 1, 4, 1, 5]
Beklenen
true