0Pricing
DSA Interview Prep · Ders

Permütasyonlar ve Kombinasyonlar

Bir listedeki tüm permütasyonları, yinelenen öğeler varken ve yokken sıralayın; ayrıca tüm k-kombinasyonlarını ve kombinasyon toplamı çeşitlerini oluşturun.

Permütasyonlar ve Kombinasyonlar, CoddyKit'te ücretsiz bir DSA Interview Prep dersidir. Bu, 4 dersinin 3. 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.

Permütasyonlar ve Kombinasyonlar

Permütasyonlar, sıranın önemli olduğu düzenlemelerdir: [1,2,3] ve [3,2,1] farklıdır. n öğenin permütasyon sayısı n! değeridir. Kombinasyonlar, sıranın önemli olmadığı seçimlerdir: {1,2} seçmek ile {2,1} seçmek aynıdır. n öğeden k'lı kombinasyonların sayısı C(n,k) = n! / (k! × (n-k)!) şeklindedir. Her ikisi de sayma, listeleme ve seçme konularındaki mülakat sorunları için temel kalıplardır.

import math

# Permutations
n = 4
print(f'Permutations of {n} items: {math.factorial(n)}')
# 4! = 24

# Combinations
for k in range(n+1):
    print(f'C({n},{k}) = {math.comb(n,k)}')
# C(4,0)=1, C(4,1)=4, C(4,2)=6, C(4,3)=4, C(4,4)=1
# Sum = 2^4 = 16 (total subsets)

Tüm Permütasyonları Üretme

Geçerli yolda hangi öğelerin bulunduğunu izlemek için bir used mantıksal dizisi kullanınız. Her adımda kullanılmamış her öğeyi deneyiniz. Keşfi tamamladıktan sonra öğeyi yeniden kullanılmamış olarak işaretleyiniz. Alt kümelerin aksine, permütasyonlar öğeleri herhangi bir sırada kullandığından start indeksi yoktur. len(path) == n olduğunda özyineleme sona erer.

def permutations(nums):
    result = []
    used = [False] * len(nums)
    def backtrack(path):
        if len(path) == len(nums):
            result.append(list(path))
            return
        for i, num in enumerate(nums):
            if not used[i]:
                used[i] = True         # CHOOSE
                path.append(num)
                backtrack(path)        # EXPLORE
                path.pop()             # UNCHOOSE
                used[i] = False
    backtrack([])
    return result

print(permutations([1, 2, 3]))
# [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

Yer Değiştirmeye Dayalı Permütasyonlar

Bir başka yaklaşım da start konumundaki öğeyi start ile n-1 arasındaki her öğeyle yer değiştirmek, özyinelemeli çağrı yapmak ve ardından yer değiştirmeyi geri almaktır. Bu yaklaşım, used dizisi olmadan diziyi yerinde değiştirir. Temel fikir, her düzeyde start konumunun solundaki her şeyin sabit olması ve bu konuma hangi öğenin yerleştirileceğinin seçilmesidir. Bu yaklaşım biraz daha az bellek kullanır ve Heap algoritmasının temelini oluşturur.

def permutations_swap(nums):
    result = []
    def backtrack(start):
        if start == len(nums):
            result.append(list(nums))
            return
        for i in range(start, len(nums)):
            nums[start], nums[i] = nums[i], nums[start]  # CHOOSE (swap)
            backtrack(start + 1)                          # EXPLORE
            nums[start], nums[i] = nums[i], nums[start]  # UNCHOOSE (swap back)
    backtrack(0)
    return result

print(permutations_swap([1, 2, 3]))
# Same 6 permutations, different order

Permütasyonlar II: Yinelenenleri Ele Alma

Girdi yinelenen değerler içerdiğinde (örneğin [1, 1, 2]), used dizisi yaklaşımı yinelenen permütasyonlar üretir. Çözüm: diziyi sıralayınız, ardından önceki özdeş öğe bu özyinelemeli çağrıda kullanılmadıysa yinelenen değeri atlayınız. Koşul: if i > 0 and nums[i] == nums[i-1] and not used[i-1]: continue. Bu, yinelenen değerlerin her zaman soldan sağa seçilmesini sağlar.

def permutations_unique(nums):
    nums.sort()
    result = []
    used = [False] * len(nums)
    def backtrack(path):
        if len(path) == len(nums):
            result.append(list(path))
            return
        for i in range(len(nums)):
            if used[i]: continue
            # Skip if this num is a duplicate and the previous dup was not used
            if i > 0 and nums[i] == nums[i-1] and not used[i-1]:
                continue
            used[i] = True
            path.append(nums[i])
            backtrack(path)
            path.pop()
            used[i] = False
    backtrack([])
    return result

print(permutations_unique([1, 1, 2]))
# [[1,1,2],[1,2,1],[2,1,1]] — 3, not 6

Sözlük Sıralamasında Sonraki Permütasyon

Sonraki Permütasyon (LeetCode 31), bir diziyi yerinde değiştirerek sözlük sıralamasında ondan sonra gelen daha büyük permütasyona dönüştürür. Algoritma: (1) nums[i] < nums[i+1] koşulunu sağlayan en sağdaki i indeksini bulunuz. (2) nums[j] > nums[i] koşulunu sağlayan en sağdaki j indeksini bulunuz. (3) nums[i] ile nums[j] değerlerini yer değiştiriniz. (4) i indeksinden sonraki son parçayı ters çeviriniz. Böyle bir i yoksa dizinin tamamını ters çeviriniz; bu işlem en küçük permütasyona dönülmesini sağlar.

def next_permutation(nums):
    n = len(nums)
    # Step 1: find rightmost i where nums[i] < nums[i+1]
    i = n - 2
    while i >= 0 and nums[i] >= nums[i+1]:
        i -= 1
    if i >= 0:
        # Step 2: find rightmost j where nums[j] > nums[i]
        j = n - 1
        while nums[j] <= nums[i]:
            j -= 1
        # Step 3: swap
        nums[i], nums[j] = nums[j], nums[i]
    # Step 4: reverse suffix after i
    nums[i+1:] = nums[i+1:][::-1]
    return nums

print(next_permutation([1, 2, 3]))  # [1,3,2]
print(next_permutation([3, 2, 1]))  # [1,2,3] (wraps)
print(next_permutation([1, 1, 5]))  # [1,5,1]

k-Kombinasyonları için Geri İzleme

n öğe arasından k öğeli tüm kombinasyonları üretiniz (LeetCode 77). Öğeleri yeniden ziyaret etmeyi önlemek ve sıralı düzeni korumak için alt kümelerdeki gibi bir başlangıç indeksi kullanınız. k - len(path) değerinden daha az öğe kaldığında budama yapınız: if len(nums) - i + 1 < k - len(path): break. Bu yaklaşım, önceki combine(n, k) ile eşdeğerdir, ancak gerçek bir dizi üzerinde çalışır.

def combinations(nums, k):
    result = []
    def backtrack(start, path):
        if len(path) == k:
            result.append(list(path))
            return
        for i in range(start, len(nums)):
            # Pruning: not enough elements left
            if len(nums) - i < k - len(path):
                break
            path.append(nums[i])
            backtrack(i + 1, path)
            path.pop()
    backtrack(0, [])
    return result

print(combinations([1,2,3,4,5], 3))
# 10 combinations: C(5,3)
import math
print(math.comb(5,3))  # 10

Kombinasyon Toplamı: Sınırsız Yeniden Kullanım

Kombinasyon Toplamı (LeetCode 39), her sayının sınırsız kez kullanılmasına izin verir. Standart kombinasyonlardan farkı şudur: start değerini i+1 konumuna ilerletmek yerine, geçerli öğenin yeniden kullanılabilmesi için i değerini iletiniz. Budama kuralları: kalan hedef 0 olursa yolu kaydediniz; negatif olursa durunuz. Sıralama, kalan tüm adaylar kalan hedefi aştığında erken sonlandırmayı sağlar.

def combination_sum(candidates, target):
    candidates.sort()
    result = []
    def backtrack(start, path, remaining):
        if remaining == 0:
            result.append(list(path))
            return
        for i in range(start, len(candidates)):
            c = candidates[i]
            if c > remaining: break  # all remaining are too big
            path.append(c)
            backtrack(i, path, remaining - c)  # reuse allowed: pass i, not i+1
            path.pop()
    backtrack(0, [], target)
    return result

print(combination_sum([2, 3, 6, 7], 7))
# [[2,2,3],[7]]

Kombinasyon Toplamı II: Yeniden Kullanım Yok, Yinelenenlerle

Kombinasyon Toplamı II (LeetCode 40), her sayıyı en fazla bir kez kullanır, ancak girdi yinelenen değerler içerebilir. İki tekniğin birleşimi kullanılır: yeniden kullanımı önlemek için start değerini i+1 konumuna ilerletmek ve sıralama sonrasında aynı düzeydeki yinelenenleri atlamak (if i > start and nums[i] == nums[i-1]: continue). Bu yaklaşım, subsets II içindeki yinelenenleri ele alma tekniğiyle combinations yaklaşımındaki yeniden kullanım kısıtını birleştirir.

def combination_sum_ii(candidates, target):
    candidates.sort()
    result = []
    def backtrack(start, path, remaining):
        if remaining == 0:
            result.append(list(path))
            return
        for i in range(start, len(candidates)):
            if candidates[i] > remaining: break
            # Skip duplicates at same level
            if i > start and candidates[i] == candidates[i-1]:
                continue
            path.append(candidates[i])
            backtrack(i + 1, path, remaining - candidates[i])  # no reuse: i+1
            path.pop()
    backtrack(0, [], target)
    return result

print(combination_sum_ii([10,1,2,7,6,1,5], 8))
# [[1,1,6],[1,2,5],[1,7],[2,6]]

Telefon Numarasının Harf Kombinasyonları

Harf Kombinasyonları (LeetCode 17), her rakamı telefon tuş takımındaki harflerle eşleştirir ve verilen rakam dizisi için olası tüm harf kombinasyonlarını üretir. Bu, her konumda rakamın eşlemesinden bir harf seçtiğimiz ve özyinelemeli çağrı yaptığımız bir geri izleme problemidir. Ortalama olarak her rakamda k harf bulunan n uzunluğundaki bir dizi için zaman karmaşıklığı O(kⁿ) olur.

def letter_combinations(digits):
    if not digits: return []
    phone = {
        '2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl',
        '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz'
    }
    result = []
    def backtrack(index, path):
        if index == len(digits):
            result.append(''.join(path))
            return
        for letter in phone[digits[index]]:
            path.append(letter)
            backtrack(index + 1, path)
            path.pop()
    backtrack(0, [])
    return result

print(letter_combinations('23'))
# ['ad','ae','af','bd','be','bf','cd','ce','cf']

Permütasyonlar ve Kombinasyonların Karşılaştırılması

Temel yapısal farklar şunlardır: Permütasyonlar — başlangıç indeksi kullanılmaz; yeniden kullanımı önlemek için bir used dizisi veya yer değiştirme kullanılır; ağaçta her düzeyde n seçenek bulunur ve toplam n! yaprak vardır. Kombinasyonlar — sıralamayı zorunlu kılmak için başlangıç indeksi kullanılır ve C(n,k) yaprak bulunur. Kombinasyon Toplamı — yeniden kullanım için başlangıç ilerletilmez ve hedefe göre budama yapılır. Yeni bir sorunu bu üç biçimden biriyle eşleştirmek, doğru şablonu hemen seçmenizi sağlar.

# Pattern summary:
# Permutations: for i in range(n); if not used[i]; no start advancement
# Combinations: for i in range(start, n); advance start → i+1
# Combo Sum (reuse): for i in range(start, n); advance start → i (same)

# Quick reference:
import math
n = 5
print(f'Perm({n})   = n! = {math.factorial(n)}')
print(f'Comb({n},2) = C(n,k) = {math.comb(n,2)}')
print(f'Comb({n},3) = {math.comb(n,3)}')
# Also: subsets = sum(C(n,k) for k=0..n) = 2^n
print(f'Subsets({n}) = 2^n = {2**n}')

Karmaşıklık ve Mülakat İpuçları

Listeleme için zaman karmaşıklıkları: Permütasyonlar O(n × n!), Kombinasyonlar O(k × C(n,k)), Kombinasyon Toplamı O(n^(T/min_val)). Bellek kullanımı, özyineleme derinliği için O(n) ve sonuçlar için O(çıktı) şeklindedir. Temel ipuçları: (1) Sıranın önemli olup olmadığını her zaman netleştiriniz (permütasyon mu, kombinasyon mu). (2) Sorulmasını beklemeden yinelenen değerlerin nasıl ele alınacağını belirtiniz. (3) Budama koşulunu her zaman açıkça ifade ediniz. (4) Büyük n değerleri için çıktının kendisinin üstel olduğunu belirtiniz — görev açısından algoritma optimaldir.

import math

# Complexity for n=10
n = 10
print(f'Permutations(10): {math.factorial(n):,} results')
print(f'Combinations(10,5): {math.comb(n,5):,} results')
print(f'Subsets(10): {2**n:,} results')

# For interview: state which pattern
# 'This is a combinations problem because order doesnt matter'
# 'I will use a start index to avoid revisiting elements'
# 'Pruning: when sum exceeds target, break (after sorting)'

Hızlı Kontrol

Bu dersteki Veri Yapıları & Algoritmalar — Kodlama Mülakatı Hazırlığı kavramlarını anlayışınızı sınayınız.

Ders Özeti

Bu derste şunları öğrendiniz: permütasyonlar, bir used dizisi ve başlangıç indeksi kullanmadan n! düzenleme üretir, kombinasyonlar, yeniden kullanımı önlemek için ilerletilen bir başlangıç indeksi kullanarak C(n,k) seçim üretir ve her iki sorundaki yinelenen değerler, sıralama yapılıp aynı özyineleme düzeyinde tekrarlar atlanarak ele alınır. Sırada, geri izlemeyi N Vezirleri problemine uygulayacak ve kısıt yayılımını inceleyeceğiz.

Sıkça Sorulan Sorular

“Permütasyonlar ve Kombinasyonlar” dersi ücretsiz mi?

Evet — “Permütasyonlar ve Kombinasyonlar” 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.

“Permütasyonlar ve Kombinasyonlar” dersinde ne öğreneceğim?

Bir listedeki tüm permütasyonları, yinelenen öğeler varken ve yokken sıralayın; ayrıca tüm k-kombinasyonlarını ve kombinasyon toplamı çeşitlerini oluşturun. 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 3. dersidir.

“Permütasyonlar ve Kombinasyonlar” 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. Geri İzleme Şablonu: Seç, Keşfet, Seçimi Geri Al
  2. Alt Kümeler ve Kuvvet Kümesi
  3. Permütasyonlar ve Kombinasyonlar
  4. N-Vezir ve Kısıt Yayılımı
← DSA Interview Prep Sayfasına Dön