ترکیب‌ها و جایگشت‌ها

تولید همه جایگشت‌ها، ترکیب‌ها و ترکیب‌های تکراری با Backtracking — سه مسئله خواهر و تفاوت‌های ظریفشان

سه مسئله خواهر

مسئلهتعریفتعدادمثال [1,2,3]
جایگشت (Permutation)همه چیدمان‌هاn![1,2,3], [2,1,3]...
ترکیب (Combination)انتخاب kتایی بدون ترتیبC(n,k)[1,2], [1,3], [2,3]
زیرمجموعه (Subset)همه ترکیب‌ها (هر اندازه)2ⁿ[], [1], [1,2]...

جایگشت‌ها — هر عنصر یک‌بار

در هر سطح، هر عنصر استفاده‌نشده را انتخاب کن:

def permute(nums):
    result = []
    def backtrack(path, remaining):
        if not remaining:
            result.append(path[:])
            return
        for i in range(len(remaining)):
            backtrack(path + [remaining[i]],
                      remaining[:i] + remaining[i+1:])
    backtrack([], nums)
    return result

ترکیب‌ها — ترتیب مهم نیست

ترفند طلایی: فقط به جلو! هر انتخاب از «بعد از آخرین انتخاب» شروع شود — تکرار [1,2] و [2,1] حذف می‌شود:

def combine(n, k):
    result = []
    def backtrack(start, path):
        if len(path) == k:
            result.append(path[:])
            return
        for i in range(start, n + 1):   # از start به بعد!
            path.append(i)
            backtrack(i + 1, path)       # بعدی: بعد از i
            path.pop()
    backtrack(1, [])
    return result

ترکیب با تکرار (عناصر تکراری)

سه تفاوت ظریف:

  1. ورودی مرتب شود
  2. در حلقه: i > start و nums[i] == nums[i-1] ← رد کن (تکرار در همین سطح)
  3. backtrack با i (نه i+1) — عنصر قابل استفاده مجدد (اگر مجاز باشد)

پیچیدگی‌ها

همه نمایی‌اند — طبیعت «همه حالت‌ها»!

نکته: در پایتون، itertools (permutations، combinations) این‌ها را آماده دارد — اما پیاده‌سازی Backtracking برای مصاحبه و درک الگو ضروری است!

جمع‌بندی

این مبحث بخشی از دوره آموزش کامل الگوریتم‌ها است.

ابزارهای مرتبط