المصفوفة هي مجرد مصفوفة ثنائية الأبعاد، ولكن في المقابلات غالبًا ما تمثل شبكة - خريطة أو لوحة أو متاهة. كل خلية grid[r][c] هي عقدة، وجيرانها عبارة عن خلايا مجاورة.
grid = [
[1, 1, 0],
[1, 0, 0],
[0, 0, 1]
]
الصف r، العمود c، الأبعاد m × n. بسيطة - ولكن الأنماط المبنية في الأعلى قوية.
بدلًا من كتابة أربع عبارات if منفصلة، استخدم مصفوفة اتجاه:
# 4-directional (up, down, left, right)
dirs = [(-1,0), (1,0), (0,-1), (0,1)]
# 8-directional (includes diagonals)
dirs = [(-1,0),(1,0),(0,-1),(0,1),
(-1,-1),(-1,1),(1,-1),(1,1)]
for dr, dc in dirs:
nr, nc = r + dr, c + dc
if 0 <= nr < m and 0 <= nc < n:
# process neighbour
هذا هو المقتطف الأكثر قابلية لإعادة الاستخدام في مشاكل الشبكة.
يعثر BFS على أقصر مسار في شبكة غير مرجحة. ابدأ من المصدر، واستكشف جميع الجيران على مسافة 1، ثم المسافة 2، وهكذا.
from collections import deque
def shortest_path(grid, start, end):
m, n = len(grid), len(grid[0])
q = deque([(start[0], start[1], 0)])
visited = {(start[0], start[1])}
dirs = [(-1,0),(1,0),(0,-1),(0,1)]
while q:
r, c, dist = q.popleft()
if (r, c) == end:
return dist
for dr, dc in dirs:
nr, nc = r+dr, c+dc
if 0<=nr<m and 0<=nc<n and (nr,nc) not in visited and grid[nr][nc]==0:
visited.add((nr, nc))
q.append((nr, nc, dist+1))
return -1
تعبئة الفيضان (مثل أداة دلو الطلاء): من خلية البداية، قم بتغيير جميع الخلايا المتصلة من نفس اللون. يعمل كل من DFS أو BFS.
عدد الجزر: مسح الشبكة؛ عندما تجد ، قم بتشغيل DFS/BFS لوضع علامة على الجزيرة بأكملها كزيارة، ثم قم بزيادة العدد.
تسجيل الدخول للانضمام إلى النقاش
1def num_islands(grid):
count = 0
for r in range(len(grid)):
for c in range(len(grid[0])):
if grid[r][c] == '1':
dfs(grid, r, c) # mark island
count += 1
return count
في ”عدد الجزر”، لماذا نضع علامة على الخلايا التي تمت زيارتها أثناء DFS؟
جميع البرتقال الفاسد في البداية هي مصادر. ادفعهم جميعًا إلى قائمة الانتظار في الوقت 0، ثم BFS. كل مستوى هو دقيقة واحدة. عندما يفرغ الطابور، تحقق من بقاء أي برتقال طازج.
Minute 0: [2, 1, 1] 2 = rotten, 1 = fresh
[1, 1, 0]
[0, 1, 1]
Minute 4: [2, 2, 2] All reachable oranges rotten
[2, 2, 0]
[0, 2, 2]
الفكرة الرئيسية: BFS متعدد المصادر يبدأ من عقد متعددة في وقت واحد، وليس من عقدة واحدة.
ما الذي يجعل ”البرتقال المتعفن” مختلفًا عن BFS القياسي؟
قم بالسير على المصفوفة بترتيب حلزوني: يمين ← أسفل ← يسار ← أعلى، مع تقليص الحدود بعد كل تمريرة.
def spiral(matrix):
res = []
top, bot = 0, len(matrix) - 1
left, right = 0, len(matrix[0]) - 1
while top <= bot and left <= right:
for c in range(left, right + 1):
res.append(matrix[top][c])
top += 1
for r in range(top, bot + 1):
res.append(matrix[r][right])
right -= 1
if top <= bot:
for c in range(right, left - 1, -1):
res.append(matrix[bot][c])
bot -= 1
if left <= right:
for r in range(bot, top - 1, -1):
res.append(matrix[r][left])
left += 1
return res
قم بتدوير مصفوفة N×N في اتجاه عقارب الساعة في مكانها: قم بالتبديل (بدّل [r][c] بـ [c][r])، ثم اعكس كل صف.
Original → Transpose → Reverse rows
1 2 3 1 4 7 7 4 1
4 5 6 → 2 5 8 → 8 5 2
7 8 9 3 6 9 9 6 3
نوعان شائعان:
المسارات الفريدة: قم بحساب المسارات من أعلى اليسار إلى أسفل اليمين مع التحرك لليمين أو للأسفل فقط. dp[r][c] = dp[r-1][c] + dp[r][c-1].
الحد الأدنى لمجموع المسار: نفس الفكرة ولكن اختر الحد الأدنى للمسار الوارد.
غالبًا ما تكون هذه هي المقدمة اللطيفة للبرمجة الديناميكية ثنائية الأبعاد.
في مشكلة المسارات الفريدة، ما هو dp[0][c] لأي عمود c؟
| نمط | تقنية | المشكلة الرئيسية | |---------|----------|-------------| | أقصر طريق (غير مرجح) | بي إف إس | المتاهة أقصر طريق | | المكونات المتصلة | دي إف إس / بي إف إس | عدد الجزر | | انتشار متعدد المصادر | متعدد المصادر BFS | البرتقال المتعفن | | أمر الاجتياز | مؤشرات الحدود | مصفوفة حلزونية | | تحويل في المكان | تبديل + عكس | تدوير الصورة | | عد المسارات | موانئ دبي | مسارات فريدة | | البحث في الشبكة المصنفة | الدرج / بحث ثنائي | بحث في مصفوفة ثنائية الأبعاد |