جاري التحميل...
جاري التحميل...
خوارزميات الفرز والبحث الأساسية والمتقدمة
ينظم الفرز البيانات لاسترجاعها بكفاءة. يقلل Binary Search وقت البحث من O(n) إلى O(log n) على البيانات المرتبة.
💡 ما سنتعلمه:
خوارزمية Binary Search، خوارزميات الفرز (Quick Sort، Merge Sort)، ومشاكل البحث المتقدمة.
يعمل Binary Search على المصفوفات المرتبة عن طريق تقسيم فترات البحث إلى نصف بشكل متكرر.
💡 المعادلة الرئيسية:
mid = left + Math.floor((right - left) / 2). قارن mid مع الهدف، أeliminate نصفًا في كل خطوة.
يمكن تكييف Binary Search لإيجاد الحدود أو القمم أو الإجابة في نطاق من القيم الممكنة.
💡 التنويعات:
البحث الكلاسيكي، الظهور الأول/الأخير، البحث في مصفوفة مدورة، الإجابة على نطاق مرتب (BS على الإجابة).
فهم خوارزميات الفرز يساعد في اختيار المناسب منها بناءً على حجم البيانات والذاكرة والمتطلبات.
💡 الخوارزميات الشائعة:
Quick Sort: O(n log n) متوسط، مدمج. Merge Sort: O(n log n) مضمون، مستقر. Insertion Sort: O(n²)، جيد للبيانات الصغيرة.
عندما تكون الإجابة في نطاق [low, high]، استخدم Binary Search لإيجاد الحد الأدنى/الأقصى للإجابة الصالحة.
💡 النمط:
حدد نطاق البحث، لكل mid تحقق من الصلاحية، حرّك يسارًا أو يمينًا بناءً على الصلاحية.
تعامل مع مصفوفة 2D مرتبة كمصفوفة مسطحة مرتبة وطبّق Binary Search مع تحويل الفهرس.
💡 تحويل الفهرس:
row = Math.floor(mid / cols)، col = mid % cols. O(log(m*n)).
مصفوفة مرتبة من الأعداد الصحيحة `nums` وعدد صحيح `target`. اكتب دالة تبحث عن `target` في `nums` وترجع الفهرس الخاص به. إذا لم يتم العثور عليه، ارجع `-1`. يجب عليك كتابة خوارزمية ب SearchesO(log n) في التعقيد الزمني.
📋 أمثلة:
nums = [-1, 0, 3, 5, 9, 12], target = 9
4
nums = [-1, 0, 3, 5, 9, 12], target = 2
-1
💡 تلميح:
function search(nums, target) {
let left = 0;
let right = nums.length - 1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
if (nums[mid] === target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}لديك `n` إصدارًا من 1 إلى `n`. يوجد إصدار واحد سيء هو أول إصدار سيء يسبّب فشل جميع الإصدارات اللاحقة. لديك دالة `isBadVersion(version)` التي ترجع `true` إذا كان الإصدار سيئًا و `false` إذا لم يكن سيئًا. اكتب دالة تجد أول إصدار سيء. يجب أن تستخدم أقل عدد ممكن من الاستدعاءات لدالة `isBadVersion`.
📋 أمثلة:
n = 5, output = isBadVersion(4) = true, isBadVersion(3) = false
4
n = 1, output = isBadVersion(1) = true
1
💡 تلميح:
var solution = function (isBadVersion) {
return function (n) {
let left = 1;
let right = n;
while (left < right) {
const mid = left + Math.floor((right - left) / 2);
if (isBadVersion(mid)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
};
};أعطى عدد صحيح موجب `num`، ارجع `true` إذا كان `num` مربعًا كاملًا. يجب عليك حل المشكلة بدون استخدام مكتبة أو دالة جذر تربيعي.
📋 أمثلة:
num = 16
true
num = 14
false
💡 تلميح:
function isPerfectSquare(num) {
if (num < 2) return true;
let left = 2;
let right = Math.floor(num / 2);
while (left <= right) {
const mid = left + Math.floor((right - left) / 2);
const square = mid * mid;
if (square === num) {
return true;
} else if (square < num) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return false;
}مصفوفة مرتبة بأعداد صحيحة مميزة `nums` تم تدويرها في مكان ما قبل الدوران (مثلاً `[0,1,2,4,5,6,7]` قد تصبح `[4,5,6,7,0,1,2]`). أعطى `target`، ارجع الفهرس الخاص به في `nums`. إذا لم يتم العثور عليه، ارجع `-1`. يجب أن تعطي حلًا بتعقيد زمني O(log n).
📋 أمثلة:
nums = [4,5,6,7,0,1,2], target = 0
4
nums = [4,5,6,7,0,1,2], target = 3
-1
💡 تلميح:
function search(nums, target) {
let left = 0;
let right = nums.length - 1;
while (left <= right) {
const mid = left + Math.floor((right - left) / 2);
if (nums[mid] === target) {
return mid;
}
if (nums[left] <= nums[mid]) {
if (nums[left] <= target && target < nums[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
} else {
if (nums[mid] < target && target <= nums[right]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return -1;
}مصفوفة أعداد صحيحة `nums`، عنصر ذروة هو عنصر أكبر من جاريه. اكتب دالة تعيد فهرس عنصر ذروة في `nums`. يمكنك افتراض أن `nums[-1] = nums[n] = -∞`. يجب أن تعطي حلًا بتعقيد زمني O(log n).
📋 أمثلة:
nums = [1,2,3,1]
2
nums = [1,2,1,3,5,6,4]
5
💡 تلميح:
function findPeakElement(nums) {
let left = 0;
let right = nums.length - 1;
while (left < right) {
const mid = left + Math.floor((right - left) / 2);
if (nums[mid] < nums[mid + 1]) {
left = mid + 1;
} else {
right = mid;
}
}
return left;
}كوكو تريد أكل موز. لديها مصفوفة `piles` حيث `piles[i]` هو عدد الموز في الرصيف الثالث. لديها `h` ساعة لأكل جميع الموز. في كل ساعة، تأكل الموز من رصيف واحد؛ إذا أكلت من رصيف فيه `x` موز، ستأكل `k` موز في الساعة (أقل من أو يساوي `x`). اكتب دالة تجد الحد الأدنى لعدد الموز التي يمكنها أكلها في الساعة `k` ل أن تأكل جميع الموز في الوقت المحدد.
📋 أمثلة:
piles = [3,6,7,11], h = 8
4
piles = [30,11,23,4,20], h = 5
30
💡 تلميح:
function minEatingSpeed(piles, h) {
let left = 1;
let right = Math.max(...piles);
while (left < right) {
const mid = left + Math.floor((right - left) / 2);
let totalHours = 0;
for (const pile of piles) {
totalHours += Math.ceil(pile / mid);
}
if (totalHours <= h) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}لديك مصفوفة ثنائية الأبعاد `matrix` من الأعداد الصحيحة حيث صفوفها مرتبة من الأصغر إلى الأكبر، وصف يبدأ بقيمة أكبر من نهاية الصف السابق له. أعطى `target`، ارجع `true` إذا كان `target` موجودًا في `matrix`.
📋 أمثلة:
matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
true
matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
false
💡 تلميح:
function searchMatrix(matrix, target) {
const rows = matrix.length;
const cols = matrix[0].length;
let left = 0;
let right = rows * cols - 1;
while (left <= right) {
const mid = left + Math.floor((right - left) / 2);
const midValue = matrix[Math.floor(mid / cols)][mid % cols];
if (midValue === target) {
return true;
} else if (midValue < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return false;
}صمم بنية بيانات تعتمد على الوقت لتخزين القيم. Implement the following: `set(key, value, timestamp)`: store a value tied to a key and timestamp. `get(key, timestamp)`: return the most recent value for `key` with `timestamp` less than or equal to the given time. If no value found, return '""'.
📋 أمثلة:
set("foo", "bar", 1), get("foo", 1) => "bar", get("foo", 3) => "bar", set("foo", "bar2", 4), get("foo", 4) => "bar2", get("foo", 5) => "bar2"["bar","bar","bar2","bar2"]
💡 تلميح:
var TimeMap = function () {
this.map = new Map();
};
TimeMap.prototype.set = function (key, value, timestamp) {
if (!this.map.has(key)) {
this.map.set(key, []);
}
this.map.get(key).push([value, timestamp]);
};
TimeMap.prototype.get = function (key, timestamp) {
if (!this.map.has(key)) return "";
const entries = this.map.get(key);
let left = 0;
let right = entries.length - 1;
let result = "";
while (left <= right) {
const mid = left + Math.floor((right - left) / 2);
if (entries[mid][1] <= timestamp) {
result = entries[mid][0];
left = mid + 1;
} else {
right = mid - 1;
}
}
return result;
};مصفوفتان مرتبتان `nums1` و `nums2` بحجمي `m` و `n` على التوالي. اكتب دالة تجد الوسيط. يجب أن يكون التعقيد الزمني O(log(min(m, n))).
📋 أمثلة:
nums1 = [1,3], nums2 = [2]
2.00000
nums1 = [1,2], nums2 = [3,4]
2.50000
💡 تلميح:
function findMedianSortedArrays(nums1, nums2) {
if (nums1.length > nums2.length) {
[nums1, nums2] = [nums2, nums1];
}
const m = nums1.length;
const n = nums2.length;
let left = 0;
let right = m;
while (left <= right) {
const partitionX = Math.floor((left + right) / 2);
const partitionY = Math.floor((m + n + 1) / 2) - partitionX;
const maxX =
partitionX === 0 ? -Infinity : nums1[partitionX - 1];
const minX =
partitionX === m ? Infinity : nums1[partitionX];
const maxY =
partitionY === 0 ? -Infinity : nums2[partitionY - 1];
const minY =
partitionY === n ? Infinity : nums2[partitionY];
if (maxX <= minY && maxY <= minX) {
if ((m + n) % 2 === 0) {
return (Math.max(maxX, maxY) + Math.min(minX, minY)) / 2;
} else {
return Math.max(maxX, maxY);
}
} else if (maxX > minY) {
right = partitionX - 1;
} else {
left = partitionX + 1;
}
}
throw new Error("Input arrays are not sorted");
}لديك `n` كرة مغناطيسية على خط عدد صحيح `position` حيث `position[i]` هو موقع الكرة الثانية. اختر `m` كرات ووضعها على مواقع مختلفة. القوة المغناطيسية بين كرتين هي القيمة المطلقة للفرق بين موقعيهما. اكتب دالة تجد الحد الأدنى للقوة المغناطيسية القصى بين أي كرتين. يجب أن تزيد `position` لتكون أكبر قوة مغناطيسية ممكنة هي الأقل.
📋 أمثلة:
position = [1,2,3,4,7], m = 3
3
position = [5,4,3,2,1,1000000000], m = 2
999999999
💡 تلميح:
function maxDistance(position, m) {
position.sort((a, b) => a - b);
let left = 1;
let right = Math.floor(
(position[position.length - 1] - position[0]) / (m - 1)
);
while (left <= right) {
const mid = left + Math.floor((right - left) / 2);
if (canPlaceBalls(position, m, mid)) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return right;
}
function canPlaceBalls(position, m, minForce) {
let count = 1;
let lastPosition = position[0];
for (let i = 1; i < position.length; i++) {
if (position[i] - lastPosition >= minForce) {
count++;
lastPosition = position[i];
if (count >= m) return true;
}
}
return false;
}