0Pricing
DSA Interview Prep · Ders

Yolları Çözümleme ve Yolları Sayma

Basamak-harf eşlemeleri içeren yolları çözme problemini Fibonacci benzeri DP olarak çözün, ardından değişken adım boyutlarına sahip bir merdivendeki yolları sayın.

Yolları Çözümleme ve Yolları Sayma, CoddyKit'te ücretsiz bir DSA Interview Prep dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, DSA Interview Prep öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. DSA Interview Prep kursu toplamda 4 dersten oluşur.

Kod Çözme Yolları Problemi

Kod Çözme Yolları (LeetCode 91), bir basamak dizisini harflere eşler: 'A'=1, 'B'=2, ..., 'Z'=26. Kodlanmış bir basamak dizisi verildiğinde, onu çözmenin farklı yollarının sayısını bulun. Örneğin '12', (1+2) ile 'AB' veya (12) ile 'L' olarak çözülebilir; yani 2 yol vardır. '226' değeri 'BZ' (2+26), 'VF' (22+6) veya 'BBF' (2+2+6) olabilir; yani 3 yol vardır. Baştaki sıfırlar bazı çözümlemeleri geçersiz kılar.

# Encoding: A=1, B=2, ..., Z=26
# '12' → 'AB' or 'L' → 2 ways
# '226' → 'BZ' or 'VF' or 'BBF' → 3 ways
# '06' → invalid (no letter for '0')
# '10' → 'J' only → 1 way (only valid as 10, not 1+0)

s = '226'
print('Decodings for', s, ':', 3)  # Expected: 3

Kod Çözme Yolları için DP Formülasyonu

dp[i] = s[:i] dizgesini çözmenin yolu sayısı olarak tanımlayın. Temel durumlar: dp[0] = 1 (boş dizge, tek yol) ve s[0] != '0' ise dp[1] = 1, aksi hâlde 0. Geçiş: s[i-1] != '0' ise dp[i-1] değerini ekleyin (tek basamaklı çözüm). 10 ≤ int(s[i-2:i]) ≤ 26 ise dp[i-2] değerini ekleyin (iki basamaklı çözüm). Bu, geçerlilik kontrolleri içeren temel olarak Fibonacci örüntüsüdür.

def num_decodings(s):
    n = len(s)
    dp = [0] * (n + 1)
    dp[0] = 1  # empty prefix
    dp[1] = 0 if s[0] == '0' else 1
    
    for i in range(2, n + 1):
        # Single digit decode
        if s[i-1] != '0':
            dp[i] += dp[i-1]
        # Two digit decode
        two_digit = int(s[i-2:i])
        if 10 <= two_digit <= 26:
            dp[i] += dp[i-2]
    return dp[n]

print(num_decodings('12'))   # 2
print(num_decodings('226'))  # 3
print(num_decodings('06'))   # 0

Baştaki Sıfır Tuzağı

Kod Çözme Yolları problemindeki en zor kısım sıfırları ele almaktır. Tek başına bulunan '0' çözülemez (0'a karşılık gelen bir harf yoktur); bu nedenle s[i-1] == '0' ise dp[i-1] değerini eklemeyin. İkinci basamak olarak kullanılan '0' yalnızca iki basamaklı sayı 10 veya 20 ise geçerlidir. '30' veya '40' (ve daha büyük sayılar) 26'yı aştıkları için geçersizdir. Yalnızca two_digit ≤ 26 koşulunu değil, her zaman 10 ≤ two_digit ≤ 26 koşulunu denetleyin.

def num_decodings(s):
    if not s or s[0] == '0': return 0
    n = len(s)
    dp = [0] * (n + 1)
    dp[0] = 1
    dp[1] = 1  # s[0] != '0' guaranteed by guard above
    for i in range(2, n + 1):
        one = int(s[i-1])
        two = int(s[i-2:i])
        if one != 0: dp[i] += dp[i-1]  # valid single digit
        if 10 <= two <= 26: dp[i] += dp[i-2]  # valid two digits
    return dp[n]

print(num_decodings('10'))   # 1 (only 'J')
print(num_decodings('30'))   # 0 (30 > 26, '0' alone invalid)
print(num_decodings('100'))  # 0 (dp[2]=1 then '00' invalid, single '0' invalid)

Bellek Kullanımı Optimize Edilmiş Kod Çözme Yolları

Fibonacci'de olduğu gibi, çözüm yolları yineleme bağıntısı yalnızca iki konum geriye baktığından, iki değişken kullanarak O(n) alanını O(1) alanına düşürebilirsiniz. İki adım gerideki değer için prev2, bir adım gerideki değer için prev1 kullanın. Her adımda curr değerini ikisinden hesaplayın ve ardından değerleri kaydırın. Bu, Fibonacci → iki değişkenli optimizasyonla aynıdır.

def num_decodings_o1(s):
    if not s or s[0] == '0': return 0
    prev2 = 1  # dp[0]
    prev1 = 1  # dp[1]
    for i in range(2, len(s) + 1):
        curr = 0
        if s[i-1] != '0':
            curr += prev1
        two = int(s[i-2:i])
        if 10 <= two <= 26:
            curr += prev2
        prev2, prev1 = prev1, curr
    return prev1

print(num_decodings_o1('226'))   # 3
print(num_decodings_o1('12'))    # 2
print(num_decodings_o1('0'))     # 0

Merdiven Çıkma Yollarını Sayma

Merdiven Çıkma (LeetCode 70) şu soruyu sorar: Bir seferde 1 veya 2 basamak çıkabiliyorsanız, n basamaklı bir merdiveni kaç farklı şekilde çıkabilirsiniz? Bu, tam olarak Fibonacci dizisidir: ways(n) = ways(n-1) + ways(n-2). ways(1)=1, ways(2)=2, ways(3)=3, ways(4)=5. Bir seferde en fazla k basamak çıkabildiğinizde genelleme şu şekilde olur: ways(n) = sum(ways(n-1), ..., ways(n-k)).

def climb_stairs(n):
    if n <= 2: return n
    prev2, prev1 = 1, 2
    for _ in range(3, n + 1):
        prev2, prev1 = prev1, prev1 + prev2
    return prev1

for i in range(1, 8):
    print(f'climb_stairs({i}) = {climb_stairs(i)}')
# 1, 2, 3, 5, 8, 13, 21 — Fibonacci!

Değişken Adım Sayılarıyla Merdiven Çıkma

Belirli bir kümeden herhangi bir sayıda basamak çıkabildiğinizde (ör. {1, 3, 5}), yineleme bağıntısı dp[i] = sum(dp[i-k] for k in steps if i-k >= 0) hâline gelir. Bellek kullanımını verimli tutmak için max(steps) boyutunda kayan pencere kullanın. Bu, sınırsız sırt çantası sayma çeşididir; her adım boyutu istenen sayıda kullanılabilir.

def count_ways(n, steps):
    dp = [0] * (n + 1)
    dp[0] = 1  # one way to stay at ground
    for i in range(1, n + 1):
        for step in steps:
            if i >= step:
                dp[i] += dp[i - step]
    return dp[n]

# Steps of 1 or 2 (classic climbing stairs)
print(count_ways(5, [1, 2]))    # 8
# Steps of 1, 3, or 5
print(count_ways(5, [1, 3, 5])) # 5
# Steps of 2 or 3
print(count_ways(6, [2, 3]))    # 3 (2+2+2, 3+3, 2+4-invalid, 2+2+2, 3+3, 3+2+1-no...)

Minimum Maliyetle Merdiven Çıkma

Minimum Maliyetle Merdiven Çıkma (LeetCode 746), her basamağa bir maliyet atar ve tepeye ulaşmanın minimum maliyetini sorar. i. basamaktan i+1 veya i+2 konumuna sıçrayabilirsiniz. Yineleme bağıntısı dp[i] = cost[i] + min(dp[i-1], dp[i-2]) şeklindedir. 0. veya 1. basamaktan başlayabilirsiniz. Yanıt min(dp[n-1], dp[n-2]) olur.

def min_cost_climbing(cost):
    n = len(cost)
    if n == 1: return cost[0]
    dp = [0] * n
    dp[0] = cost[0]
    dp[1] = cost[1]
    for i in range(2, n):
        dp[i] = cost[i] + min(dp[i-1], dp[i-2])
    return min(dp[-1], dp[-2])  # can start from step 0 or 1

print(min_cost_climbing([10, 15, 20]))      # 15
print(min_cost_climbing([1, 100, 1, 1, 1, 100, 1, 1, 100, 1]))  # 6

Kod Çözme Yolları II: Joker Basamak

Kod Çözme Yolları II (LeetCode 639), 1-9 arasındaki herhangi bir basamağı temsil edebilen joker karakteri '*' ekler. Bu, geçerli çözüm sayısını büyük ölçüde artırır. Tek bir '*' 9 yol sağlar (1-9 arasındaki herhangi bir basamak olarak). İki '*' birlikte 9×9 iki basamaklı birleşim oluşturabilir; ancak yalnızca 26 veya daha küçük olanlar geçerlidir (11-19 = 9 yol, 21-26 = 6 yol → '**' için toplam 15 yol). Dikkatli bir durum çözümlemesi gerekir.

def num_decodings_ii(s):
    MOD = 10**9 + 7
    prev2, prev1 = 1, 9 if s[0] == '*' else (0 if s[0] == '0' else 1)
    for i in range(1, len(s)):
        curr = 0
        c, p = s[i], s[i-1]
        # Single digit
        if c == '*': curr += 9 * prev1
        elif c != '0': curr += prev1
        # Two digits
        if p == '*' and c == '*': curr += 15 * prev2  # 11-19(9) + 21-26(6)
        elif p == '*': curr += (2 if c <= '6' else 1) * prev2
        elif c == '*': curr += (9 if p == '1' else (6 if p == '2' else 0)) * prev2
        else:
            two = int(p + c)
            if 10 <= two <= 26: curr += prev2
        prev2, prev1 = prev1, curr % MOD
    return prev1 % MOD

print(num_decodings_ii('*'))   # 9
print(num_decodings_ii('1*'))  # 18

Fibonacci Bağlantısı

Hem Kod Çözme Yolları hem de Merdiven Çıkma, görünüşte farklı olsa da Fibonacci ailesinden problemlerdir. dp[i] yalnızca dp[i-1] ve dp[i-2] değerlerine bağlı olan her DP, Fibonacci biçimindedir ve O(1) alanla çözülebilir. Geçerlilik kontrolleri (sıfır basamaklar, adım boyutları) hangi geçişlerin etkin olduğunu değiştirir; ancak temeldeki iki konum geriye bakma yapısını değiştirmez. Bu aileyi ilk bakışta tanımak, mülakatlarda hızlı çözüm üretmek için değerli bir örüntüdür.

# Fibonacci family: dp[i] = f(dp[i-1], dp[i-2])
# Fibonacci itself:        dp[i] = dp[i-1] + dp[i-2]
# Climbing stairs:         dp[i] = dp[i-1] + dp[i-2]
# Decode ways:             dp[i] = (dp[i-1] if one_valid) + (dp[i-2] if two_valid)
# Min cost stairs:         dp[i] = cost[i] + min(dp[i-1], dp[i-2])
# House robber:            dp[i] = max(dp[i-1], nums[i] + dp[i-2])

# All solved with 2 rolling variables:
prev2, prev1 = 0, 1
for _ in range(10):
    prev2, prev1 = prev1, prev1 + prev2
print('Fibonacci F(10):', prev1)  # 89

Izgaradaki Yolları Sayma

İlgili bir sayma problemi şöyledir: m×n boyutunda bir ızgara verildiğinde, yalnızca sağa veya aşağı hareket ederek sol üstten sağ alta kaç benzersiz yol gidebilir? Yanıt, binom katsayısı C(m+n-2, m-1)'dir. DP çözümü, dp[i][j] = dp[i-1][j] + dp[i][j-1] olacak şekilde 2B bir tablo doldurur. Bu, Fibonacci merdiveninin 2B sürümüdür; her hücre, üstündeki ve solundaki hücrenin toplamıdır.

def unique_paths(m, n):
    dp = [[1] * n for _ in range(m)]
    for i in range(1, m):
        for j in range(1, n):
            dp[i][j] = dp[i-1][j] + dp[i][j-1]
    return dp[m-1][n-1]

# Or use math for O(1) solution
import math
def unique_paths_math(m, n):
    return math.comb(m + n - 2, m - 1)

print(unique_paths(3, 7))         # 28
print(unique_paths_math(3, 7))    # 28
print(unique_paths(3, 3))         # 6

Mülakat Tuzaklarının Özeti

Kod Çözme Yolları problemindeki yaygın tuzaklar: (1) Tek başına bulunan '0'ın geçersiz olduğunu unutmak — dp[i-1] değerini eklemeden önce her zaman s[i-1] != '0' koşulunu denetleyin. (2) two_digit >= 10 koşulunu denetlemeden two_digit <= 26 kullanmak — '07', 'G' olarak çözülmemelidir. (3) dp[n] yerine dp[n-1] döndürmek — tablo 1 tabanlı olduğundan dp[n] dizgenin tamamına karşılık gelir. DP tablonuz girdiden bir eleman daha uzunsa dizi indislerini her zaman iki kez kontrol edin.

# Common bug: checking two_digit <= 26 without >= 10
def buggy_decode(s):
    dp = [0] * (len(s) + 1)
    dp[0] = dp[1] = 1
    for i in range(2, len(s) + 1):
        if s[i-1] != '0': dp[i] += dp[i-1]
        two = int(s[i-2:i])
        # BUG: '07' gives two=7, and 7 <= 26 would add dp[i-2]
        # Fix: require two >= 10
        if 10 <= two <= 26: dp[i] += dp[i-2]  # CORRECT
    return dp[len(s)]

print(buggy_decode('06'))   # 0 (correct, '0' alone invalid)
print(buggy_decode('07'))   # 0 (correct, '07' not valid, '0' alone invalid)
print(buggy_decode('27'))   # 1 (only 'BG', 27>26 so no two-digit)

Hızlı Kontrol

Bu dersteki Veri Yapıları ve Algoritmalar — Kodlama Mülakatına Hazırlık kavramlarını anlayıp anlamadığınızı sınayın.

Ders Özeti

Bu derste şunları öğrendiniz: Kod Çözme Yolları, tek basamaklı (sıfır olmayan) ve iki basamaklı (10-26) çözümler için geçerlilik koşulları içeren Fibonacci benzeri bir yineleme bağıntısını izler, Merdiven Çıkma ve Minimum Maliyetli Merdiven, O(1) alanla çözülebilen saf Fibonacci çeşitleridir ve iki konum geriye bakan Fibonacci ailesini tanımak, mülakatlar sırasında önemli ölçüde zaman kazandırır. Sırada, Benzersiz Yollar ve Izgaralarda Minimum Yol Toplamı ile 2B DP'yi inceleyeceğiz.

Sıkça Sorulan Sorular

“Yolları Çözümleme ve Yolları Sayma” dersi ücretsiz mi?

Evet — “Yolları Çözümleme ve Yolları Sayma” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve DSA Interview Prep kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. DSA Interview Prep kursu toplamda 4 dersten oluşur.

“Yolları Çözümleme ve Yolları Sayma” dersinde ne öğreneceğim?

Basamak-harf eşlemeleri içeren yolları çözme problemini Fibonacci benzeri DP olarak çözün, ardından değişken adım boyutlarına sahip bir merdivendeki yolları sayın. DSA Interview Prep ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

DSA Interview Prep öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te DSA Interview Prep, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.

“Yolları Çözümleme ve Yolları Sayma” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu DSA Interview Prep dersinde kod yazıp çalıştırabilir miyim?

Evet. Her DSA Interview Prep dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. Ev Soyguncusu: Al veya Atla Bağıntısı
  2. Maksimum Alt Dizi ve Maksimum Çarpımlı Alt Dizi
  3. Sözcük Bölme ve Dizeyi Parçalara Ayırma
  4. Yolları Çözümleme ve Yolları Sayma
← DSA Interview Prep Sayfasına Dön