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 orderPermü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 6Sö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)) # 10Kombinasyon 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
- Geri İzleme Şablonu: Seç, Keşfet, Seçimi Geri Al
- Alt Kümeler ve Kuvvet Kümesi
- Permütasyonlar ve Kombinasyonlar
- N-Vezir ve Kısıt Yayılımı