جاري التحميل...
جاري التحميل...
استخدام مكدس وطابور لحل المشاكل
المكدس والقائمة هما هياكل بيانات خطية تحتفظ بالعناصر في ترتيب محدد. يتبع المكدس LIFO (الأخير يدخل الأول يخرج)، تتبع القائمة FIFO (الأول يدخل الأول يخرج).
💡 ما سنتعلمه:
عمليات المكدس، عمليات القائمة، المكدس الأحادي، ومشاكل مثل Valid Parentheses و Daily Temperatures.
يتبع المكدس LIFO: العنصر الأخير المُضاف هو الأول الذي يُزال. العمليات الرئيسية: push، pop، top، isEmpty.
💡 حالات الاستخدام:
الأقواس المتوازنة، التراجع/إعادة، مكدس استدعاء الدوال، تجذور DFS، تعبيرات التقييم.
تتبع القائمة FIFO: العنصر الأول المُضاف هو الأول الذي يُزال. العمليات الرئيسية: enqueue، dequeue، front، isEmpty.
💡 حالات الاستخدام:
تجذور BFS، جدولة المهام، قائمة الطباعة، قوائم الرسائل.
يحافظ المكدس الأحادي على العناصر بترتيب تصاعدي أو تنازلي. يُستخدم لإيجاد العنصر الأكبر/الأصغر التالي بفعالية.
💡 النمط:
لكل عنصر، أزل العناصر التي تنتهك الأحادية، عالج العناصر المُزالة، أضف العنصر الحالي.
تُستخدم المكدسات لتقييم تعبيرات postfix وفك ترميز الهياكل المتداخلة مثل النصوص مع الأقواس.
💡 النمط:
لـ Reverse Polish Notation: أضف الأرقام، عند العامل أزل عاملين وأضف النتيجة.
يمكن تنفيذ القائمة باستخدام مكدسين: واحد للإدخال وواحد للإخراج، لتحقيق عمليات O(1) متوسطة.
💡 النمط:
مكدس الإدخال للـ enqueue. عندما يكون الإخراج فارغًا، انقل الكل من الإدخال إلى الإخراج للـ dequeue/peek.
أكتب دالة تتحقق مما إذا كان النص المكون من الأقواس (){}[] هو نص متوازن (valid). نص الأقواس متوازن إذا:
📋 أمثلة:
s = "()"
true
s = "()[]{}"true
s = "(]"
false
s = "([)]"
false
s = "{[]}"true
💡 تلميح:
function isValid(s) {
const stack = [];
const map = {
')': '(',
'}': '{',
']': '['
};
for (const char of s) {
if (char === '(' || char === '{' || char === '[') {
stack.push(char);
} else {
if (stack.length === 0 || stack[stack.length - 1] !== map[char]) {
return false;
}
stack.pop();
}
}
return stack.length === 0;
}صمم مكدساً (Stack) يدعم العمليات الأساسية (push, pop, top) وعملية إضافية هي getMin() لإرجاع أقل عنصر في المكدس. يجب أن تكون العمليات الثلاث الأساسية جميعها بأقل تعقيد ممكن O(1).
📋 أمثلة:
MinStack stack = new MinStack(); stack.push(-2); stack.push(0); stack.push(-3); stack.getMin();
-3
stack.pop(); stack.top();
0
stack.getMin();
-2
💡 تلميح:
class MinStack {
constructor() {
this.stack = [];
this.minStack = [];
}
push(val) {
this.stack.push(val);
if (this.minStack.length === 0 || val <= this.minStack[this.minStack.length - 1]) {
this.minStack.push(val);
}
}
pop() {
const val = this.stack.pop();
if (val === this.minStack[this.minStack.length - 1]) {
this.minStack.pop();
}
return val;
}
top() {
return this.stack[this.stack.length - 1];
}
getMin() {
return this.minStack[this.minStack.length - 1];
}
}قم بتنفيذ طابور (Queue) باستخدام مكدسين (Stacks). يجب أن تدعم الدوال enqueue و dequeue و peek و isEmpty بتعقيد زمني amortized O(1).
📋 أمثلة:
MyQueue queue = new MyQueue(); queue.enqueue(1); queue.enqueue(2); queue.peek();
1
queue.dequeue();
1
queue.isEmpty();
false
💡 تلميح:
class MyQueue {
constructor() {
this.inputStack = [];
this.outputStack = [];
}
enqueue(x) {
this.inputStack.push(x);
}
dequeue() {
this.peek();
return this.outputStack.pop();
}
peek() {
if (this.outputStack.length === 0) {
while (this.inputStack.length > 0) {
this.outputStack.push(this.inputStack.pop());
}
}
return this.outputStack[this.outputStack.length - 1];
}
isEmpty() {
return this.inputStack.length === 0 && this.outputStack.length === 0;
}
}معطى مصفوفة من درجات الحرارة اليومية، أرجع مصفوفة حيث answer[i] هو عدد الأيام التي يجب الانتظار للحصول على درجة حرارة أعلى. إذا لم تكن هناك يوم أبعد لهذا، أبقِ answer[i] == 0.
📋 أمثلة:
temperatures = [73,74,75,71,69,72,76,73]
[1,1,4,2,1,1,0,0]
temperatures = [30,40,50,60]
[1,1,1,0]
temperatures = [30,60,90]
[1,1,0]
💡 تلميح:
function dailyTemperatures(temperatures) {
const n = temperatures.length;
const answer = new Array(n).fill(0);
const stack = [];
for (let i = 0; i < n; i++) {
while (stack.length > 0 && temperatures[i] > temperatures[stack[stack.length - 1]]) {
const prevIndex = stack.pop();
answer[prevIndex] = i - prevIndex;
}
stack.push(i);
}
return answer;
}أكتب دالة تولّد جميع التركيبات الصحيحة والأقواس المتوازنة من n أزواج من الأقواس.
📋 أمثلة:
n = 3
"((()))""(()())""(())()""()(())""()()()"
n = 1
"()"
💡 تلميح:
function generateParenthesis(n) {
const result = [];
function backtrack(current, open, close) {
if (current.length === 2 * n) {
result.push(current);
return;
}
if (open < n) {
backtrack(current + '(', open + 1, close);
}
if (close < open) {
backtrack(current + ')', open, close + 1);
}
}
backtrack('', 0, 0);
return result;
}أكتب دالة تحسب قيمة تعبير Reverse Polish Notation. عبارة RPN هي تعبير حيث كل عملية تأتي بعد أعدادها.
📋 أمثلة:
tokens = ["2","1","+","3","*"]
9 ((2 + 1) * 3 = 9)
tokens = ["4","13","5","/","+"]
6 (4 + (13 / 5) = 6)
tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"]
22
💡 تلميح:
function evalRPN(tokens) {
const stack = [];
for (const token of tokens) {
if (token === '+' || token === '-' || token === '*' || token === '/') {
const b = stack.pop();
const a = stack.pop();
switch (token) {
case '+': stack.push(a + b); break;
case '-': stack.push(a - b); break;
case '*': stack.push(a * b); break;
case '/': stack.push(Math.trunc(a / b)); break;
}
} else {
stack.push(Number(token));
}
}
return stack[0];
}أكتب دالة فك تشفير نص مشفر بتنسيق معين: k[encoded_string]، حيث k عدد صحيح يمثل تكرار النص المشفر داخل الأقواس.
📋 أمثلة:
s = "3[a2[c]]"
"accaccacc"
s = "2[abc]3[cd]ef"
"abcabccdcdcdef"
s = "abc3[cd]xyz"
"abccdcdcdxyz"
💡 تلميح:
function decodeString(s) {
const numStack = [];
const strStack = [];
let currentNum = 0;
let currentStr = '';
for (const char of s) {
if (char >= '0' && char <= '9') {
currentNum = currentNum * 10 + parseInt(char);
} else if (char === '[') {
numStack.push(currentNum);
strStack.push(currentStr);
currentNum = 0;
currentStr = '';
} else if (char === ']') {
const num = numStack.pop();
const prevStr = strStack.pop();
currentStr = prevStr + currentStr.repeat(num);
} else {
currentStr += char;
}
}
return currentStr;
}معطى مصفوفة تمثل ارتفاعات أعمدة في رسم بياني شريطي، أرجع مساحة أكبر مستطيل في الرسم البياني.
📋 أمثلة:
heights = [2,1,5,6,2,3]
10
heights = [2,4]
4
💡 تلميح:
function largestRectangleArea(heights) {
const stack = [];
let maxArea = 0;
const extendedHeights = [...heights, 0];
for (let i = 0; i < extendedHeights.length; i++) {
while (stack.length > 0 && extendedHeights[i] < extendedHeights[stack[stack.length - 1]]) {
const height = extendedHeights[stack.pop()];
const width = stack.length === 0 ? i : i - stack[stack.length - 1] - 1;
maxArea = Math.max(maxArea, height * width);
}
stack.push(i);
}
return maxArea;
}Stack (المكدس):
المبدأ
LIFO — Last In, First Out
العمليات
push, pop, top, isEmpty — جميعها O(1)
الاستخدامات الشائعة
الأقواس المتوازنة، DFS، Undo/Redo، Function Calls
Queue (الطابور):
المبدأ
FIFO — First In, First Out
العمليات
enqueue, dequeue, front, isEmpty — جميعها O(1)
الاستخدامات الشائعة
BFS، قوائم الانتظار، معالجة الأحداث، جدولة المهام