LeetCode 448 · Find All Numbers Disappeared in an Array · Easy

Kayıp Sayıları Bulmak

Çözümün her adımını burada izleyebilirsin. Bir dizi seç, İleri'ye bas ya da Oynat'a tıkla; gördüğümüz her sayının kutusunun nasıl işaretlendiğini ve işaretsiz kalan kutuların kayıp sayıları nasıl gösterdiğini gör.

Fikir üç adımda

  1. 1

    Her sayının bir kutusu var

    Sayılar 1 ile n arasında, dizide de tam n kutu var. x sayısının kutusu nums[x - 1]: 1'in kutusu nums[0], 2'nin kutusu nums[1] ve böyle devam eder.

  2. 2

    Gördüğün sayının kutusunu işaretle

    Bir sayıyı görünce kutusundaki değeri negatif yap. Değer kaybolmaz, sadece işareti değişir; okurken Math.Abs ile asıl sayıya geri dönersin.

  3. 3

    Pozitif kalan kutular kayıp

    nums[i] sonunda hâlâ pozitifse i + 1 sayısı dizide hiç yok demektir. Toplarken negatif kutuları da geri çevirip diziyi eski hâline getiriyoruz.

Adım adım izle

nums (her kutunun altında hangi sayının kutusu olduğu yazıyor)

negatif: bu sayı görüldü kayıp sayı, result'a eklendi okunan eleman (num) bakılan kutu (box ya da i)

Değişkenler

result

Kod (Solution.cs içindeki metot)

Neden O(1) ekstra bellek?

Diziyi iki kez geziyoruz: O(n) zaman. İşaretleri ayrı bir dizide değil, nums'ın kendi kutularında, sayının işaretinde tutuyoruz. Fazladan sadece num, box ve i gibi birkaç değişken var: O(1) ekstra bellek. Döndürdüğümüz liste bu hesaba katılmıyor.

Daha kolay bir çözüm de var: görülen sayıları bool[] seen = new bool[n + 1] dizisinde işaretleyip sonra false kalanları toplamak. O da O(n) zamanda çalışır ama n + 1 elemanlık ayrı bir dizi açtığı için O(n) bellek kullanır. Bu sayfadaki çözüm aynı işaretlemeyi nums'ın içinde yaptığı için o diziye gerek kalmıyor.

İkinci döngüde negatif kutuları yeniden pozitife çeviriyoruz. Böylece metodu çağıran kod dizisini verdiği gibi geri alıyor. Bunun için ayrı bir döngü de gerekmiyor; kayıp sayıları toplarken aynı turda yapılıyor.