لماذا تعتبر لغة C++ اللغة المثالية لـ LeetCode (وكيف لا تفشل)
\n\nإذا فتحت LeetCode وفكرت: "سأكتب كل شيء بلغة Python، فهي موجزة"، - توقف. من أجل النمو القوي والفهم الحقيقي للخوارزميات، تتفوق لغة C++ على أي لغة أخرى. لماذا؟ لأنها تجبرك على التفكير في الذاكرة والسرعة ودقائق التنفيذ. لا يوجد sort() "سحري" دون فهم كيفية عمله.
في هذه المقالة، لن نقوم فقط بسرد المسائل. سنوضح كيفية التفكير بلغة C++ عند حل مسائل LeetCode، وما هي هياكل البيانات المطلوبة حقًا، وسنقدم قوالب جاهزة للكود. ستتعلم لماذا std::vector هو أفضل صديق لك، و std::unordered_map هو سلاحك السري.
هل أنت مستعد؟ هيا بنا.
\n\nأفضل 5 هياكل بيانات في C++ لـ LeetCode
\n\nقبل أن تندفع لحل المسائل، تحتاج إلى تجميع "الترسانة". إليك ما ستحتاجه حقًا في 90% من الحالات:
\n\n- \n
- std::vector - مصفوفة ديناميكية. كل ما يتعلق بالتسلسلات، الفواصل الزمنية، المصفوفات. \n
- std::unordered_map - جدول تجزئة. للعد، البحث عن التكرارات، مسائل مجموع رقمين. \n
- std::set / std::unordered_set - مجموعات. عندما تحتاج إلى التحقق بسرعة من وجود عنصر. \n
- std::stack / std::queue / std::deque - للاجتيازات، متواليات الأقواس، BFS/DFS. \n
- std::pair - لا غنى عنه لتخزين الأزواج (مثل الإحداثيات + القيمة). \n
إليك مثال على شكل غلاف أساسي للتحليل التكراري باستخدام جدول التجزئة:
\n\n#include <unordered_map>\n#include <vector>\n#include <string>\n\nstd::unordered_map<std::string, int> countWords(const std::vector<std::string>& words) {\n std::unordered_map<std::string, int> freq;\n for (const auto& w : words) {\n freq[w]++;\n }\n return freq;\n}\n\n\nأرأيت؟ أقل كود، أقصى فائدة.
\n\nكيفية التعامل مع المسألة: قائمة مراجعة لـ C++
\n\nخطأ المبتدئ هو كتابة الكود فورًا. الطريق الصحيح هو أولاً فهم بنية البيانات. بالنسبة لـ C++، هذا أمر بالغ الأهمية، لأن الاختيار الخاطئ للحاوية قد يكلفك تجاوز الحد الزمني (TLE).
\n\nالخطوة 1. حدد نوع المسألة
\n- \n
- المصفوفات / السلاسل النصية → vector, string \n
- البحث عن التكرارات → unordered_set \n
- البرمجة الديناميكية → vector<vector<int>> \n
- الرسوم البيانية → vector<vector<int>> أو unordered_map<int, vector<int>> \n
الخطوة 2. اختر النموذج الخوارزمي
\n- \n
- الخوارزمية الجشعة - إذا كانت المسألة تتعلق بالحد الأدنى/الأقصى \n
- البحث الثنائي - للبيانات المرتبة \n
- المؤشران المزدوجان - للفواصل الزمنية \n
- DFS/BFS - للاجتيازات \n
الخطوة 3. اكتب الهيكل الأساسي
\nلا تحاول التحسين فورًا. أولاً حل عملي، ثم إعادة الهيكلة.
\n\nتحليل مسألة حقيقية: Two Sum (LeetCode #1)
\n\nكلاسيكية. حتى لو كنت قد حللتها من قبل، فإنها تتجلى بشكل مختلف في C++.
\n\nالشرط: لديك مصفوفة من الأعداد الصحيحة nums وعدد صحيح target. أعد فهارس الرقمين اللذين مجموعهما يساوي target.
حل سيء (O(n²)):
\nstd::vector<int> twoSum_brute(std::vector<int>& nums, int target) {\n for (int i = 0; i < nums.size(); ++i) {\n for (int j = i + 1; j < nums.size(); ++j) {\n if (nums[i] + nums[j] == target) {\n return {i, j};\n }\n }\n }\n return {};\n}\n\n\nحل جيد (O(n) باستخدام unordered_map):
\n#include <unordered_map>\n\nstd::vector<int> twoSum(std::vector<int>& nums, int target) {\n std::unordered_map<int, int> seen; // القيمة -> الفهرس