الجزر في الشبكة: الجيران والحدود
درس 10 من 11
10الجزر في الشبكة: الجيران والحدود
الصورة الكبيرةالشبكة رسم بياني مخفي: كل خانة عقدة، وجيرانها الأربعة أضلاع. أغلب مسائل الشبكات هي «مرّ على الخانات، وانظر للجيران».
ماذا تشاهد في الرسم: الحلقة الأساسية لأي مسألة شبكة. يتغيّر فقط ما تفعله بكل جار.
خارطة هذا الجزء
المفاهيم بالترتيب، اضغط أيًّا منها للقفز إليه:
طريقان إلى نفس الفكرة
تخيّل خريطة مربعات: الأخضر يابسة والأزرق ماء. لتعرف كم جزيرة، تبدأ من أي مربع أخضر وتلوّن كل الأخضر المتصل به، ثم تبحث عن أخضر لم يُلوَّن بعد. كل مرة تبدأ تلوينًا جديدًا تكون وجدت جزيرة جديدة.
الاتجاهات [(1,0),(-1,0),(0,1),(0,-1)]، والتحقّق 0 <= nr < rows and 0 <= nc < cols. DFS بمكدّس صريح يتجنّب حد التكرار في بايثون للشبكات الكبيرة. الزمن O(rows × cols) لأن كل خانة تُزار مرة. للمحيط: كل خانة يابسة لها 4 حواف، وكل حافة تجاور يابسة أو تقع داخل الشبكة على يابسة لا تُحسب، أو بصيغة أخرى: 4 × اليابسة − 2 × الأزواج المتجاورة.
قبل أن تبدأ
🔁الحلقات المتداخلة
تمرّ على صفوف وأعمدة.
🗂️المكدّس
تعرف push وpop.
الفكرة الجوهرية
1الجيران والحدود
اكتب الاتجاهات الأربعة في قائمة، وتحقّق من الحدود قبل قراءة أي خانة. هذا يعدّ جيران كل خانة يابسة:
grid = [[0, 1, 0],
[1, 1, 1],
[0, 1, 0]]
DIRS = [(1, 0), (-1, 0), (0, 1), (0, -1)]
rows, cols = len(grid), len(grid[0])
def land_neighbours(r, c):
count = 0
for dr, dc in DIRS:
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] == 1:
count += 1
return count
print(land_neighbours(1, 1), land_neighbours(0, 1))grid[-1] لا يعطي خطأ بل آخر صف! بدون فحص الحدود يصبح الجار «خارج الخريطة» خانة من الطرف الآخر.2عدّ الجزر بالبحث بالعمق
كل خانة يابسة لم تُزر تبدأ جزيرة جديدة. نلوّن الجزيرة كلها بمكدّس حتى لا نعدّها مرة أخرى، ونحسب مساحتها أثناء ذلك:
grid = [[1, 1, 0, 0],
[1, 0, 0, 1],
[0, 0, 1, 1],
[0, 0, 0, 1]]
DIRS = [(1, 0), (-1, 0), (0, 1), (0, -1)]
rows, cols = len(grid), len(grid[0])
seen = set()
def explore(r, c):
stack, area = [(r, c)], 0
seen.add((r, c))
while stack:
r, c = stack.pop()
area += 1
for dr, dc in DIRS:
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] == 1 and (nr, nc) not in seen:
seen.add((nr, nc))
stack.append((nr, nc))
return area
areas = [explore(r, c) for r in range(rows) for c in range(cols)
if grid[r][c] == 1 and (r, c) not in seen]
print("islands:", len(areas), "areas:", areas)3تمرين: المحيط
المحيط هو عدد حواف اليابسة التي تلمس ماء أو حافة الخريطة. لا تحتاج DFS هنا: مرّ على كل خانة يابسة، وأضف 4، واطرح 1 لكل جار يابسة (استخدم land_neighbours أعلاه). اختبر: خانة يابسة وحيدة محيطها 4، وخانتان متجاورتان محيطهما 6، وشبكة الصليب في المثال الأول محيطها 12.
مثال محلول
المسألة: صف واحد [[1,1,1]]. التحليل: 3 خانات × 4 = 12 حافة. الأزواج المتجاورة: (0,0)-(0,1) و(0,1)-(0,2)، كل زوج يخفي حافتين. الجواب: 12 − 4 = 8، وهو محيط مستطيل 3×1.
خرافة مقابل حقيقة
| الخرافة | الحقيقة |
|---|---|
| القطري جار. | في أغلب المسائل الجيران أربعة فقط. اقرأ التعريف، فبعض المسائل تعدّ ثمانية. |
| التكرار (recursion) أسهل دائمًا لـ DFS. | أقصر، لكنه يصطدم بحد التكرار في بايثون للشبكات الكبيرة. المكدّس الصريح آمن. |
أين تقابله في العمل
🗺️الخرائط
مناطق متصلة في صور الأقمار الصناعية.
🎨أداة الدلو في الرسم
تعبئة منطقة متصلة بلون واحد.
اختبر فهمك
ما محيط خانتي يابسة متجاورتين أفقيًا؟
4+4 ناقص حافتين مشتركتين = 6.
لماذا نعلّم الخانات المزارة؟
بلا تعليم يعود البحث لنفس الخانات بلا نهاية.
ما زمن عدّ الجزر؟
كل خانة تُزار مرة واحدة وتُفحص جيرانها الأربعة.
بطاقات مراجعة سريعة
تحقق من فهمك
ماذا يعطي grid[-1] في بايثون؟
آخر صف، لا خطأ. لهذا فحص الحدود ضروري.
هل تحتاج DFS للمحيط؟
لا، يكفي المرور على كل خانة وعدّ جيرانها.
كيف تعدّ جارًا قطريًا لو طُلب؟
أضف الاتجاهات الأربعة القطرية إلى DIRS.
مصادر هذا الدرس
مرتّبة بالنوع. ابدأ بالتوثيق الرسمي إذا تبي المرجع الدقيق، وبالمقال أو الفيديو إذا تبي الشرح أولًا.
خلّصت الدرس؟
سجّل الدخول ليُحفظ تقدّمك.