ورقة غش للتعرّف على الأنماط
اربط 15 إشارة شائعة في المسائل (مثل مصفوفة مرتبة، والحاجة إلى جميع التوافيق، وتعظيم قيمة مع وجود قيد) بأنماط الخوارزميات التي تحلّها بأسرع طريقة.
ورقة غش للتعرّف على الأنماط درس مجاني في Coding Interview Prep على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Coding Interview Prep، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Coding Interview Prep 4 دروس في المجموع.
لعبة التعرّف على الأنماط خلال 60 ثانية
في مقابلة فعلية، لديك تقريبًا 60 ثانية بعد قراءة المشكلة لتحديد النمط الخوارزمي المناسب قبل أن يتوقع منك المحاور بدء كتابة الشيفرة. وهذه أهم مهارة ينبغي تطويرها؛ فالمهم ليس حفظ التطبيقات، بل معرفة الأداة التي يجب استخدامها.
ينشأ التعرّف على الأنماط من ربط إشارات المشكلة (الكلمات والقيود الواردة في نص المشكلة) بعائلات الخوارزميات المعروفة. وبمجرد تحديد النمط، تصبح عملية التطبيق أشبه بملء قالب. يقدم هذا الدرس ورقة غش منهجية تتناول أكثر 15 إشارة شيوعًا للمشكلات والأنماط المقابلة لها.
# The recognition process
recognition_steps = [
'1. Read the problem once fully (do not start coding)',
'2. Identify the data structure: array, string, tree, graph, matrix?',
'3. Identify the ask: find min/max, count ways, enumerate, detect cycle...?',
'4. Note the constraint: n<=20 (bitmask), sorted (binary search), DAG (topo sort)?',
'5. Map signal -> pattern',
'6. State the pattern and complexity to the interviewer before coding',
'7. Handle edge cases mentally before writing',
]
for step in recognition_steps:
print(step)الإشارات 1-3: أنماط المصفوفات والسلاسل النصية
أكثر إشارات المشكلات شيوعًا في المصفوفات والسلاسل النصية:
- مصفوفة مرتبة + البحث عن هدف → البحث الثنائي O(log n)
- العثور على زوج أو ثلاثية مجموعها يساوي الهدف → مؤشّران O(n) إذا كانت المصفوفة مرتبة، أو جدول تجزئة O(n) إذا لم تكن مرتبة
- أطول أو أقصر مصفوفة فرعية أو سلسلة فرعية تحقق شرطًا → النافذة المنزلقة O(n)
- أقصى أو أدنى مجموع لمصفوفة فرعية متجاورة → خوارزمية Kadane O(n)
- اكتشاف التكرارات → مجموعة تجزئة O(n) أو الفرز O(n log n)
إذا كانت المصفوفة مرتبة، ففكّر دائمًا في البحث الثنائي أولًا. أما إذا كانت غير مرتبة، ويُطلب إيجاد مجموع هدف بزمن O(n)، فغالبًا ما يكون الحل جدول تجزئة للبحث عن القيمة المكملة.
# Quick recognition: array/string signals
signals = [
('Sorted array, find element', 'Binary search O(log n)'),
('Find two elements summing to K', 'Sort+two-ptr O(n log n) or hash O(n)'),
('Longest subarray with property P', 'Sliding window (variable size) O(n)'),
('Max sum contiguous subarray', 'Kadane algorithm O(n)'),
('Anagram/permutation check', 'Frequency map (Counter) O(n)'),
('Contains duplicate', 'Hash set O(n)'),
('Merge two sorted arrays/lists', 'Two pointers O(n+m)'),
('Rotate / shift array', 'Reverse trick O(n) in-place'),
('Next permutation', 'Find rightmost ascent + swap + reverse'),
('Maximum product subarray', 'Track max and min (handles negatives)'),
]
for signal, pattern in signals:
print(f'{signal:45s} => {pattern}')الإشارات 4-6: أنماط الأشجار والرسوم البيانية
إشارات مشكلات الأشجار والرسوم البيانية والأنماط المناسبة لها:
- الاجتياز مستوىً بعد مستوى / أقصر مسار في رسم بياني غير موزون → BFS باستخدام deque O(V+E)
- استكشاف جميع المسارات / اكتشاف الدورات / ترتيب DFS → DFS تكراري أو递归 O(V+E)
- BST + خصائص الاجتياز الترتيبي (العنصر رقم k، الترتيب المرتب) → DFS بالاجتياز الترتيبي O(n)
- السلف المشترك الأدنى → نزول递归 مع تتبع المسار O(n)
- المكوّنات المتصلة / دمج مجموعتين → DSU O(n × alpha(n))
# Tree/graph signal recognition
tree_graph_signals = [
('Level-order / minimum depth / word ladder', 'BFS with deque'),
('All paths / path sum / all permutations tree', 'DFS recursive'),
('Cycle detection (undirected)', 'DFS with parent / DSU'),
('Cycle detection (directed) / course schedule', 'DFS three-color / Kahn topo sort'),
('Shortest path weighted graph', 'Dijkstra (non-neg) / Bellman-Ford (neg)'),
('All-pairs shortest path', 'Floyd-Warshall O(V^3)'),
('Topological order', 'Kahn BFS topo sort'),
('Min spanning tree', 'Kruskal (DSU) / Prim (heap)'),
('Dynamic connectivity / union-find', 'DSU path compression + union by rank'),
('Autocomplete / prefix search', 'Trie'),
('BST kth smallest / range sum', 'In-order DFS'),
]
for signal, pattern in tree_graph_signals:
print(f'{signal:50s} => {pattern}')الإشارات 7-9: إشارات البرمجة الديناميكية
يصعب التعرّف على إشارات DP أكثر من غيرها. ابحث عن الكلمات المفتاحية التالية:
- «عدد الطرق لـ...» → DP للعدّ (جمع أعداد الحلول الفرعية)
- «أدنى أو أقصى تكلفة لتحقيق...» → DP للتحسين (اختيار الحد الأدنى أو الأقصى من الحلول الفرعية)
- «هل يمكننا تحقيق...» (قابلية التحقيق) → DP منطقي (عملية OR للحلول الفرعية)
- مشكلة فرعية يحددها مؤشّران في سلسلتين نصيتين → DP ثنائي الأبعاد (LCS، ومسافة التحرير)
- اختيار العناصر أو تخطيها ضمن قيد سعة → DP لحقيبة الظهر
- بنية فرعية مثلى + مشكلات فرعية متداخلة → افحص شجرة الاستدعاءات بحثًا عن استدعاءات مكررة → DP
# DP signal recognition
dp_signals = [
('Number of ways to climb stairs / decode string', '1D DP (Fibonacci-like)'),
('Minimum cost to reach end / coin change', '1D DP (greedy fails)'),
('Longest increasing subsequence', '1D DP O(n^2) or patience sort O(n log n)'),
('Longest common subsequence of two strings', '2D DP O(mn)'),
('Edit distance between two strings', '2D DP O(mn) (LCS variant)'),
('Partition array into two equal subsets', '0/1 knapsack boolean DP'),
('Fill knapsack with max value under weight limit', '0/1 knapsack optimisation DP'),
('Burst balloons / matrix chain multiplication', 'Interval DP'),
('Palindrome partitioning minimum cuts', 'Interval DP + prefix palindrome'),
('Rob houses in circle', '1D DP × 2 (linear sub-problems)'),
]
for signal, pattern in dp_signals:
print(f'{signal:55s} => {pattern}')الإشارات 10-12: إشارات الكومة والمكدس والجشع
إشارات مشكلات الكومة والمكدس الرتيب والخوارزميات الجشعة:
- العناصر الأعلى K / العنصر الأكبر أو الأصغر رقم k → كومة (كومة صغرى لأكبر K عناصر، وكومة عظمى للعنصر الأصغر رقم k) O(n log k)
- الوسيط في تدفق مستمر → كومتان (كومة عظمى للنصف الأصغر + كومة صغرى للنصف الأكبر)
- العنصر الأكبر أو الأصغر التالي → مكدس رتيب O(n)
- أكبر مساحة لمستطيل / احتجاز الماء → مكدس رتيب O(n)
- جدولة الفواصل / زيادة عدد الفواصل غير المتداخلة إلى أقصى حد → خوارزمية جشعة (الفرز حسب وقت الانتهاء)
# Heap / stack / greedy signals
heap_stack_greedy = [
('Top-K frequent elements', 'Min-heap size K: O(n log k)'),
('Kth largest in array', 'Max-heap pop K times: O(n + k log n)'),
('Streaming median', 'Two heaps (max + min): O(log n) per insert'),
('Merge K sorted lists', 'Min-heap of (val, list_idx): O(n log k)'),
('Next greater element', 'Monotonic decreasing stack: O(n)'),
('Largest rectangle in histogram', 'Monotonic increasing stack: O(n)'),
('Sliding window maximum', 'Monotonic decreasing deque: O(n)'),
('Trapping rain water', 'Two pointers OR monotonic stack: O(n)'),
('Jump game reachability / minimum jumps', 'Greedy range expansion: O(n)'),
('Merge overlapping intervals', 'Sort by start, linear scan: O(n log n)'),
('Gas station circular', 'Greedy: start from reset point: O(n)'),
('Task scheduler with cooldown', 'Greedy: sort by frequency: O(n log n)'),
]
for signal, pattern in heap_stack_greedy:
print(f'{signal:45s} => {pattern}')الإشارات 13-15: التراجع ومعالجة البتات
إشارات مشكلات التراجع ومعالجة البتات:
- توليد جميع المجموعات الجزئية / التبديلات / التوافيق → التراجع O(2^n أو n!)
- تحقيق القيود (N-queens، وSudoku) → التراجع مع التقليم
- العثور على عنصر مفقود أو وحيد → XOR O(n)، ومساحة O(1)
- تعداد جميع المجموعات الجزئية لمجموعة صغيرة (n ≤ 20) → تعداد 2^n باستخدام قناع البتات
- عدّ البتات المضبوطة / التحقق مما إذا كان العدد قوة للعدد 2 → حيل البتات (n & (n-1))
- DP لضغط الحالة مع مجموعة صغيرة → DP باستخدام قناع البتات O(2^n × n)
# Backtracking and bit signals
bt_bit_signals = [
('Generate all subsets of array', 'Backtracking O(n * 2^n) / bitmask'),
('Generate all permutations', 'Backtracking O(n * n!)'),
('Combination sum with target', 'Backtracking with pruning'),
('Word search in grid', 'Backtracking DFS on grid O(m*n*4^L)'),
('N-queens placement', 'Backtracking with column/diag sets'),
('Find single unique element (all others x2)', 'XOR all: O(n) O(1)'),
('Missing number in 0..n', 'XOR or sum formula: O(n) O(1)'),
('Count set bits in n', 'n &= n-1 loop or DP O(n)'),
('Check power of two', 'n > 0 and n & (n-1) == 0'),
('Travelling salesman (n<=20)', 'Bitmask DP O(2^n * n^2)'),
('Number with max XOR in array', 'Trie on binary representation'),
]
for signal, pattern in bt_bit_signals:
print(f'{signal:50s} => {pattern}')تحليل القيود: ما الذي تخبرك به N
يخبرك قيد حجم الإدخال n مباشرة بالتعقيد الزمني المقبول، ومن ثم بعائلة الخوارزمية المناسبة:
- n ≤ 20: التعقيد O(2^n) أو O(n!) مقبول — DP باستخدام قناع البتات، والتراجع
- n ≤ 500: التعقيد O(n³) مقبول — Floyd-Warshall، وDP بالقوة الغاشمة
- n ≤ 5000: التعقيد O(n²) مقبول — DP الساذج، والفرز التربيعي
- n ≤ 10^6: نحتاج إلى O(n log n) — فرز الدمج، والكومة، والبحث الثنائي
- n ≤ 10^8: نحتاج إلى O(n) — مؤشّران، والنافذة المنزلقة، وDP الخطي
ينبغي أن يكون تحليل القيود خطوتك الأولى بعد قراءة المشكلة، قبل اختيار أي خوارزمية.
# Constraint -> acceptable complexity -> algorithm family
complexity_map = [
('n <= 20', 'O(2^n) or O(n!)', 'Bitmask DP, backtracking/permutations'),
('n <= 500', 'O(n^3)', 'Floyd-Warshall, cubic DP, brute force'),
('n <= 5000', 'O(n^2)', 'Quadratic DP, bubble/insertion sort'),
('n <= 100000', 'O(n log n)', 'Merge sort, heap, binary search, topo sort'),
('n <= 1000000', 'O(n)', 'Linear DP, two pointers, sliding window, hash'),
('n <= 10^8', 'O(n) tight', 'Only simplest O(n) — no large constants'),
('n <= 10^18', 'O(log n) or O(1)', 'Math / number theory, binary search on answer'),
]
print(f'{'Constraint':15s} {'Complexity':15s} {'Algorithm Family'}')
print('-'*70)
for constraint, complexity, algorithms in complexity_map:
print(f'{constraint:15s} {complexity:15s} {algorithms}')من المشكلة إلى النمط: تدريب سريع
تدرّب على هذا الربط حتى يصبح تلقائيًا. اقرأ وصف كل مشكلة وحدد النمط قبل النظر إلى الحل. فالسرعة مهمة؛ إذ ينبغي أن تحدد النمط في أقل من 60 ثانية أثناء المقابلة:
- «معطاة مصفوفة مرتبة، حدّد ما إذا كان مجموع أي عنصرين يساوي K»
- «معطاة شجرة، أوجد قطرها (أطول مسار بين أي عقدتين)»
- «معطاة n من المهام مع فترة تبريد k، أوجد الحد الأدنى لفواصل وحدة المعالجة المركزية»
- «معطاة سلسلة نصية، أوجد أطول سلسلة فرعية متناظرة»
- «معطاة الأعداد من 1 إلى n مع فقدان عدد واحد، أوجد العدد المفقود»
# Quick-fire pattern recognition answers
problems = [
('Sorted array: two elements sum to K',
'Two pointers (left from start, right from end): O(n)'),
('Tree diameter (longest path)',
'DFS returning (height, max_diameter) pair: O(n)'),
('Task scheduler with cooldown k',
'Greedy: (max_freq - 1)*(k+1) + count_of_max_freq: O(n log n)'),
('Longest palindromic substring',
'Expand around centre OR Manacher: O(n^2) or O(n)'),
('Missing number in 1..n',
'XOR all indices and values: O(n) O(1)'),
('Number of islands in binary grid',
'BFS/DFS flood fill counting connected components: O(m*n)'),
('Decode string like 3[a2[bc]] -> aaabcbcaabcbc',
'Stack to handle nested brackets: O(n)'),
('Valid parentheses [(){[]}]',
'Stack push open, pop+match on close: O(n)'),
]
for problem, solution in problems:
print(f'Q: {problem}\nA: {solution}\n')إشارات تحذيرية: عندما يفشل نمطك
حتى المهندسون ذوو الخبرة قد يختارون النمط الخاطئ في البداية. تعرّف على الإشارات التالية التي تدل على خطأ نهجك الحالي، ثم غيّر المسار:
- ينجح حل O(n²) في الاختبارات الصغيرة لكنه يتجاوز المهلة TLE في المدخلات الكبيرة → تحتاج إلى جدول تجزئة أو بحث ثنائي أو بنية رتيبة
- تفشل خوارزميتك الجشعة أمام مثال مضاد → جرّب DP
- فضاء حالات DP كبير جدًا → ابحث عن برهان جشع أو تعريف أذكى للحالة
- يعطي BFS إجابة خاطئة → تحقّق مما إذا كنت تحتاج إلى Dijkstra (للأوزان) بدلًا من BFS (لغير الموزون)
- تواجه استثناءات المؤشر الفارغ → أضف الحالات الأساسية وحواجز الحالات الطرفية قبل التطبيق
# Red flags and recovery strategies
red_flags = [
('TLE on large n', 'Check complexity; switch from O(n^2) to O(n log n) or O(n)'),
('WA with greedy', 'Find a counter-example; switch to DP or prove exchange arg'),
('DP table huge', 'State compression (bitmask/rolling array) or different state'),
('BFS gives wrong shortest path', 'Check if edges have weights; use Dijkstra instead'),
('Stack overflow in recursion', 'Add memoisation or convert to iterative with explicit stack'),
('Off-by-one in binary search', 'Use half-open intervals [lo, hi); verify with 2-element test'),
('DSU wrong answer', 'Check 0-indexed vs 1-indexed; check union direction'),
('Backtracking TLE', 'Add pruning conditions; ensure undo step is correct'),
]
print('Pattern | Recovery')
print('-'*70)
for flag, recovery in red_flags:
print(f'{flag:40s} => {recovery}')التعبير عن التعرّف على الأنماط في المقابلات
في المقابلات، يُظهر التعبير بصوت عالٍ عن طريقة تعرّفك على النمط خبرتك، ويمنح المحاور فرصة لتوجيهك إذا كنت تسير في الاتجاه الخاطئ. استخدم بنية النص التالية:
- «ألاحظ أن المصفوفة مرتبة، لذا أفكر في البحث الثنائي...»
- «تطلب المشكلة إيجاد أكبر مصفوفة فرعية، وهذه مسألة كلاسيكية لخوارزمية Kadane...»
- «نحتاج إلى جميع المجموعات الجزئية الممكنة، وهذا يشير إلى التراجع باستخدام شجرة استدعاءات...»
- «القيد n ≤ 20 يخبرني بأن 2^n = 1M مقبول، لذا قد ينجح DP باستخدام قناع البتات...»
بعد ذكر النمط، اذكر التعقيدين الزمني والمكاني قبل كتابة سطر واحد من الشيفرة. فهذا يوضح أنك تفكر في الكفاءة قبل التطبيق.
# Interview communication template
def communicate_approach(problem, pattern, time_complexity, space_complexity, edge_cases):
print(f'Problem: {problem}')
print(f'Pattern: {pattern}')
print(f'Time: {time_complexity}, Space: {space_complexity}')
print(f'Edge cases to handle: {", ".join(edge_cases)}')
print()
# Example communications
communicate_approach(
problem='Find longest substring without repeating characters',
pattern='Sliding window with a set tracking current window characters',
time_complexity='O(n)',
space_complexity='O(min(n, alphabet_size))',
edge_cases=['empty string', 'all same characters', 'all unique characters']
)
communicate_approach(
problem='Given sorted matrix, find if target exists',
pattern='Binary search or staircase search (top-right corner): eliminate row or column each step',
time_complexity='O(m + n)',
space_complexity='O(1)',
edge_cases=['empty matrix', 'single element', 'target at corners']
)بناء مفرداتك الخاصة بالتعرّف على الأنماط
أسرع طريقة لبناء مهارة التعرّف على الأنماط هي حل المشكلات في دفعات موضوعية، وليس عشوائيًا. خصص أسبوعًا كاملًا لمشكلات النافذة المنزلقة فقط، ثم انتقل إلى مشكلات المؤشّرين، ثم مشكلات DP. إن حل 20 مشكلة من النوع نفسه يبني بسرعة الحدس اللازم للتعرّف على ذلك النمط بمجرد النظر.
بعد كل مشكلة، اكتب «ملاحظة نمط» من سطر واحد: إشارة المشكلة والنمط الذي أثارته. أنشئ ورقة الغش الخاصة بك. بعد حل 200 مشكلة في دفعات موضوعية، ستتعرّف على نحو 90% من مشكلات المقابلات في أقل من 30 ثانية؛ أما نسبة 10% المتبقية فتتطلب تحليلًا دقيقًا حتى من المهندسين ذوي الخبرة.
# Personal pattern note template
pattern_notes = [
{'signal': 'sorted array + two sum', 'pattern': 'two pointers', 'example': 'LC 167 Two Sum II'},
{'signal': 'longest X without repeating', 'pattern': 'sliding window + set', 'example': 'LC 3 Longest Substring'},
{'signal': 'max sum subarray', 'pattern': 'Kadane', 'example': 'LC 53 Max Subarray'},
{'signal': 'permutations/subsets', 'pattern': 'backtracking', 'example': 'LC 46 Permutations'},
{'signal': 'tree path sum', 'pattern': 'DFS with accumulator', 'example': 'LC 112 Path Sum'},
{'signal': 'course schedule', 'pattern': 'Kahn topo sort', 'example': 'LC 207 Course Schedule'},
{'signal': 'top-K elements', 'pattern': 'min-heap size K', 'example': 'LC 215 Kth Largest'},
]
print(f'{'Signal':40s} {'Pattern':30s} {'Example'}')
print('-'*90)
for note in pattern_notes:
print(f'{note["signal"]:40s} {note["pattern"]:30s} {note["example"]}')اختبار سريع
اختبر مدى فهمك لمفاهيم Data Structures & Algorithms — Coding Interview Prep الواردة في هذا الدرس.
مراجعة الدرس
في هذا الدرس تعلمت أن: التعرّف على الأنماط يربط إشارات المشكلة بعائلات الخوارزميات؛ فالمصفوفة المرتبة تشير إلى البحث الثنائي، و«جميع المجموعات الجزئية» تشير إلى التراجع، و«أدنى تكلفة» تشير إلى DP، وأن القيد n يخبرك بالتعقيد المقبول: n ≤ 20 يسمح بـ O(2^n)، بينما يتطلب n ≤ 10^6 تعقيد O(n log n) أو أفضل، وأن التعبير عن النمط والتعقيد قبل كتابة الشيفرة يثبت الخبرة ويتيح للمحاور تقديم الملاحظات. بعد ذلك نطبّق التعرّف على الأنماط من خلال مسائل مقابلات تجريبية محددة الوقت بمستويي الصعوبة السهل والمتوسط.
الأسئلة الشائعة
هل درس «ورقة غش للتعرّف على الأنماط» مجاني؟
نعم — نص درس «ورقة غش للتعرّف على الأنماط» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Coding Interview Prep، انتقل إلى CoddyKit PRO. تتضمن دورة Coding Interview Prep 4 دروس في المجموع.
ماذا ستتعلم في «ورقة غش للتعرّف على الأنماط»؟
اربط 15 إشارة شائعة في المسائل (مثل مصفوفة مرتبة، والحاجة إلى جميع التوافيق، وتعظيم قيمة مع وجود قيد) بأنماط الخوارزميات التي تحلّها بأسرع طريقة. تتمرن على Coding Interview Prep مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Coding Interview Prep؟
لا تُشترط خبرة سابقة. Coding Interview Prep على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «ورقة غش للتعرّف على الأنماط»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Coding Interview Prep هذا؟
نعم. كل درس في Coding Interview Prep يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- ورقة غش للتعرّف على الأنماط
- مقابلة تجريبية محددة بوقت: مسائل سهلة ومتوسطة
- التعامل مع الحالات الحدّية والتواصل في المقابلة
- شرح مسائل صعبة: Word Ladder II وAlien Dictionary