vault backup: 2025-08-18 12:48:52

This commit is contained in:
Andrey Epifancev
2025-08-18 12:48:52 +04:00
parent 847ea6a810
commit f5df2726a7

View File

@@ -232,51 +232,43 @@ public int minTrucksNeeded(int[] orders, int capacity) {
---
## 📊 Задача 4: Анализ пиковых нагрузок склада
# 📊 Задача 4: Анализ пиковых нагрузок склада
### **Условие:**
## Условие:
Склад ведет учет количества активных заказов в каждый момент времени. Заказ активен с момента поступления до момента отправки. Найдите максимальное количество одновременно активных заказов.
Склад ведет учет количества активных заказов в каждый момент времени. Заказ активен с момента поступления до момента отправки (включая момент поступления, но НЕ включая момент отправки). Найдите максимальное количество одновременно активных заказов.
### **Входные данные:**
## Входные данные:
- `intervals` - массив интервалов `[start, end]`, где каждый интервал представляет время жизни заказа
1. `intervals` - массив интервалов `[start, end]`, где каждый интервал представляет время жизни заказа
### **Тестовые примеры:**
## Тестовые примеры:
**Пример 1:**
### Пример 1:
```
Вход: intervals = [[1,3],[2,6],[8,10],[15,18]]
Выход: 2
Объяснение: В момент времени 2-3 активны заказы [1,3] и [2,6]
```
**Вход:** `intervals = [[1,3],[2,6],[8,10],[15,18]]`
**Выход:** `2`
**Объяснение:** В момент времени 2 активны заказы [1,3] и [2,6]
**Пример 2:**
### Пример 2:
```
Вход: intervals = [[1,4],[4,5]]
Выход: 1
Объяснение: Заказы не пересекаются по времени
```
**Вход:** `intervals = [[1,4],[4,5]]`
**Выход:** `1`
**Объяснение:** Заказы не пересекаются по времени (первый заканчивается в момент 4, второй начинается в момент 4)
**Пример 3:**
### Пример 3:
```
Вход: intervals = [[1,5],[2,3],[4,6],[7,8]]
Выход: 3
Объяснение: В момент времени 4 активны [1,5], [2,3], [4,6]
```
**Вход:** `intervals = [[1,5],[2,3],[4,6],[7,8]]`
**Выход:** `2`
**Объяснение:** Максимальное пересечение в моменты времени 2 и 4, когда активны по 2 заказа
### **Расширенные тестовые данные:**
### Расширенные тестовые данные:
```
Вход: intervals = [[1,10],[2,4],[3,6],[4,8],[5,7],[6,9],[7,12]]
Выход: 5
Объяснение: Максимальное пересечение в районе времени 6-7
```
**Вход:** `intervals = [[1,10],[2,4],[3,6],[4,8],[5,7],[6,9],[7,12]]`
**Выход:** `4`
**Объяснение:** Максимальное пересечение в районе времени 5-6, когда активны заказы [1,10], [3,6], [4,8], [5,7]
### **Решение:**
## Решение:
```java
import java.util.*;
@@ -294,8 +286,8 @@ public int maxConcurrentOrders(int[][] intervals) {
events.add(new int[]{interval[1], -1}); // end: -1
}
// Сортируем события по времени, при равном времени сначала -1 (окончание)
events.sort((a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]);
// ИСПРАВЛЕНИЕ: При равном времени сначала обрабатываем начало заказа (+1), потом конец (-1)
events.sort((a, b) -> a[0] == b[0] ? b[1] - a[1] : a[0] - b[0]);
int maxConcurrent = 0;
int currentConcurrent = 0;
@@ -309,14 +301,87 @@ public int maxConcurrentOrders(int[][] intervals) {
}
```
**Временная сложность:** O(n log n) - сортировка событий
**Пространственная сложность:** O(n) - список событий
### Альтернативное решение (JavaScript):
### **Дополнительные вопросы:**
```javascript
function maxConcurrentOrders(intervals) {
if (!intervals || intervals.length === 0) {
return 0;
}
1. Как найти конкретный момент времени, когда достигается максимум?
2. Как адаптировать алгоритм для поиска минимального количества рабочих станций?
let events = [];
// Создаем события начала и конца заказов
for (let interval of intervals) {
events.push([interval[0], 1]); // start: +1
events.push([interval[1], -1]); // end: -1
}
// При равном времени сначала обрабатываем начало заказа (+1), потом конец (-1)
events.sort((a, b) => a[0] === b[0] ? b[1] - a[1] : a[0] - b[0]);
let maxConcurrent = 0;
let currentConcurrent = 0;
for (let event of events) {
currentConcurrent += event[1];
maxConcurrent = Math.max(maxConcurrent, currentConcurrent);
}
return maxConcurrent;
}
```
## Ключевые исправления:
1. **Сортировка событий:** При одинаковом времени сначала обрабатываем события начала заказа (+1), затем события окончания (-1). Это важно, так как заказ считается активным в момент начала, но НЕ активным в момент окончания.
2. **Объяснения к примерам:** Исправлены неточности в объяснениях результатов.
3. **Расширенный пример:** Пересчитан правильный результат.
## Сложность:
- **Временная сложность:** O(n log n) - сортировка событий
- **Пространственная сложность:** O(n) - список событий
## Дополнительные вопросы:
### 1. Как найти конкретный момент времени, когда достигается максимум?
```java
public List<Integer> findPeakTimes(int[][] intervals) {
// ... тот же код до цикла обработки событий
List<Integer> peakTimes = new ArrayList<>();
int maxConcurrent = 0;
int currentConcurrent = 0;
for (int[] event : events) {
currentConcurrent += event[1];
if (currentConcurrent > maxConcurrent) {
maxConcurrent = currentConcurrent;
peakTimes.clear();
peakTimes.add(event[0]);
} else if (currentConcurrent == maxConcurrent && event[1] == 1) {
peakTimes.add(event[0]);
}
}
return peakTimes;
}
```
### 2. Как адаптировать алгоритм для поиска минимального количества рабочих станций?
Алгоритм остается тем же - максимальное количество одновременно активных заказов и есть минимальное количество рабочих станций, необходимых для обработки всех заказов без задержек.
## Важные моменты:
- Заказ активен в интервале `[start, end)` - включая start, но исключая end
- При одновременном начале и окончании заказов сначала обрабатываем начало
- Алгоритм основан на технике "sweep line" (сканирующая прямая)
---
## 🔍 Задача 5: Поиск товаров в секционированном складе