أنماط الخوارزميات: الأنماط الـ 15 الأساسية

المؤشرات المزدوجة والنافذة المنزلقة

4 دقيقة للقراءة

هذان النمطان وحدهما يحلان نسبة كبيرة من مسائل المصفوفات والسلاسل النصية. يستبدلان الحلقات المتداخلة بحلول أنيقة بتعقيد O(n).

نمط المؤشرات المزدوجة

الفكرة بسيطة: استخدم مؤشرين يتحركان عبر هيكل البيانات، عادةً من الطرفين المتقابلين أو بسرعات مختلفة.

ثلاثة أشكال:

1. الاتجاه المعاكس (التقارب)

يُستخدم عندما تحتاج لإيجاد أزواج أو فحص التماثل.

# الحاوية ذات أكبر ماء
def max_area(height):
    left, right = 0, len(height) - 1
    max_water = 0
    while left < right:
        width = right - left
        h = min(height[left], height[right])
        max_water = max(max_water, width * h)
        if height[left] < height[right]:
            left += 1
        else:
            right -= 1
    return max_water

# مجموع اثنين (مصفوفة مرتبة)
def two_sum_sorted(numbers, target):
    left, right = 0, len(numbers) - 1
    while left < right:
        total = numbers[left] + numbers[right]
        if total == target:
            return [left + 1, right + 1]
        elif total < target:
            left += 1
        else:
            right -= 1

2. نفس الاتجاه (سريع/بطيء)

يُستخدم لإزالة التكرارات أو التقسيم أو مسائل القوائم المترابطة.

# إزالة التكرارات من مصفوفة مرتبة (في المكان)
def remove_duplicates(nums):
    if not nums:
        return 0
    slow = 0
    for fast in range(1, len(nums)):
        if nums[fast] != nums[slow]:
            slow += 1
            nums[slow] = nums[fast]
    return slow + 1

3. ثلاثة مؤشرات

توسيع للمؤشرات المزدوجة لمسائل مثل 3Sum.

# 3Sum: إيجاد جميع الثلاثيات التي مجموعها صفر
def three_sum(nums):
    nums.sort()
    result = []
    for i in range(len(nums) - 2):
        if i > 0 and nums[i] == nums[i-1]:
            continue  # تخطي التكرارات
        left, right = i + 1, len(nums) - 1
        while left < right:
            total = nums[i] + nums[left] + nums[right]
            if total == 0:
                result.append([nums[i], nums[left], nums[right]])
                while left < right and nums[left] == nums[left+1]:
                    left += 1  # تخطي التكرارات
                while left < right and nums[right] == nums[right-1]:
                    right -= 1
                left += 1
                right -= 1
            elif total < 0:
                left += 1
            else:
                right -= 1
    return result

نمط النافذة المنزلقة

نافذة تنزلق عبر مصفوفة/سلسلة نصية، تتوسع أو تنكمش لإيجاد المصفوفات الفرعية المثلى.

نافذة بحجم ثابت

# أقصى مجموع لمصفوفة فرعية بحجم k
def max_sum_subarray(nums, k):
    window_sum = sum(nums[:k])
    max_sum = window_sum
    for i in range(k, len(nums)):
        window_sum += nums[i] - nums[i - k]
        max_sum = max(max_sum, window_sum)
    return max_sum

نافذة بحجم متغير

# أطول سلسلة فرعية بدون أحرف مكررة
def length_of_longest_substring(s):
    char_set = set()
    left = 0
    max_len = 0
    for right in range(len(s)):
        while s[right] in char_set:
            char_set.remove(s[left])
            left += 1
        char_set.add(s[right])
        max_len = max(max_len, right - left + 1)
    return max_len

# أصغر نافذة فرعية
def min_window(s, t):
    from collections import Counter
    need = Counter(t)
    missing = len(t)
    left = start = 0
    min_len = float('inf')
    for right, char in enumerate(s):
        if need[char] > 0:
            missing -= 1
        need[char] -= 1
        while missing == 0:
            if right - left + 1 < min_len:
                min_len = right - left + 1
                start = left
            need[s[left]] += 1
            if need[s[left]] > 0:
                missing += 1
            left += 1
    return s[start:start + min_len] if min_len != float('inf') else ""

دليل التعرف على الأنماط

الإشارة النمط التعقيد الزمني
"مصفوفة مرتبة + إيجاد زوج" مؤشرات مزدوجة (معاكسة) O(n)
"فحص التناظر" مؤشرات مزدوجة (معاكسة) O(n)
"إزالة التكرارات في المكان" مؤشرات مزدوجة (نفس الاتجاه) O(n)
"مصفوفة فرعية بحجم K" نافذة منزلقة ثابتة O(n)
"أطول/أقصر سلسلة فرعية بشرط" نافذة منزلقة متغيرة O(n)
"3Sum / 4Sum" ترتيب + مؤشرات مزدوجة O(n^2) / O(n^3)

التالي: سنغطي البحث الثنائي والخوارزميات الجشعة -- أنماط تحسّن اتخاذ القرارات. :::

اختبار

اختبار الوحدة 3: أنماط الخوارزميات

خذ الاختبار