Longest Increasing Subsequence (LIS) uzunluğunu O(n log n) zamanda nasıl bulursunuz?

Cevap

Klasik DP çözümü O(n²)'dir; O(n log n) çözüm patience sorting fikrine dayanır: tails[k], uzunluğu k+1 olan artan alt dizilerin bitebileceği en küçük değerdir. Her yeni sayı için tails içinde binary search yaparız.

O(n²) DP

dp[i] = i indeksinde biten en uzun artan alt dizinin uzunluğu; dp[i] = 1 + max(dp[j]), j < i ve nums[j] < nums[i].

def lis_n2(nums):
    dp = [1] * len(nums)
    for i in range(len(nums)):
        for j in range(i):
            if nums[j] < nums[i]:
                dp[i] = max(dp[i], dp[j] + 1)
    return max(dp, default=0)

O(n log n) çözüm

from bisect import bisect_left

def lis(nums):
    tails = []
    for x in nums:
        i = bisect_left(tails, x)   # x'ten büyük/eşit ilk konum
        if i == len(tails):
            tails.append(x)         # en uzun diziyi uzat
        else:
            tails[i] = x            # daha küçük bir bitiş değeri bulduk
    return len(tails)

print(lis([10, 9, 2, 5, 3, 7, 101, 18]))  # 4  (2, 3, 7, 18)

Neden çalışır?

tails her zaman sıralı kalır. Bir değeri daha küçüğüyle değiştirmek, gelecekte o uzunluktaki diziyi uzatma şansını artırır ve hiçbir zaman mevcut en iyi uzunluğu azaltmaz.

Dikkat

  • tails dizisi gerçek LIS'in kendisi değildir, yalnızca uzunluğu doğrudur. Diziyi geri oluşturmak için her elemanın öncülünü (parent indeksi) saklamak gerekir.
  • "Non-decreasing" (eşitlere izin) istenirse bisect_right kullanılır.
  1. Binary search'ün zaman karmaşıklığı nedir ve neden?KolayAlgoritmalar & Veri YapılarıYazılım Müh.
  2. Two Sum: toplamı hedefe eşit olan iki elemanın indekslerini bulun.KolayAlgoritmalar & Veri YapılarıYazılım Müh.
  3. Bir parantez dizisinin geçerli olup olmadığını kontrol edin: "({[]})"KolayAlgoritmalar & Veri YapılarıYazılım Müh.
  4. Tek yönlü bağlı listeyi ters çevirin.OrtaAlgoritmalar & Veri YapılarıYazılım Müh.
  5. BFS ve DFS arasındaki fark nedir? Hangisini ne zaman kullanırsınız?OrtaAlgoritmalar & Veri YapılarıYazılım Müh.
  6. get ve put işlemleri O(1) olan bir LRU Cache tasarlayın.ZorAlgoritmalar & Veri YapılarıYazılım Müh.

Bu konuda başka bir soru biliyor musun?

Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.

Soru ekle