vault backup: 2025-08-18 12:48:52
This commit is contained in:
@@ -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]]`
|
||||||
Вход: intervals = [[1,3],[2,6],[8,10],[15,18]]
|
**Выход:** `2`
|
||||||
Выход: 2
|
**Объяснение:** В момент времени 2 активны заказы [1,3] и [2,6]
|
||||||
Объяснение: В момент времени 2-3 активны заказы [1,3] и [2,6]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Пример 2:**
|
### Пример 2:
|
||||||
|
|
||||||
```
|
**Вход:** `intervals = [[1,4],[4,5]]`
|
||||||
Вход: intervals = [[1,4],[4,5]]
|
**Выход:** `1`
|
||||||
Выход: 1
|
**Объяснение:** Заказы не пересекаются по времени (первый заканчивается в момент 4, второй начинается в момент 4)
|
||||||
Объяснение: Заказы не пересекаются по времени
|
|
||||||
```
|
|
||||||
|
|
||||||
**Пример 3:**
|
### Пример 3:
|
||||||
|
|
||||||
```
|
**Вход:** `intervals = [[1,5],[2,3],[4,6],[7,8]]`
|
||||||
Вход: intervals = [[1,5],[2,3],[4,6],[7,8]]
|
**Выход:** `2`
|
||||||
Выход: 3
|
**Объяснение:** Максимальное пересечение в моменты времени 2 и 4, когда активны по 2 заказа
|
||||||
Объяснение: В момент времени 4 активны [1,5], [2,3], [4,6]
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Расширенные тестовые данные:**
|
### Расширенные тестовые данные:
|
||||||
|
|
||||||
```
|
**Вход:** `intervals = [[1,10],[2,4],[3,6],[4,8],[5,7],[6,9],[7,12]]`
|
||||||
Вход: intervals = [[1,10],[2,4],[3,6],[4,8],[5,7],[6,9],[7,12]]
|
**Выход:** `4`
|
||||||
Выход: 5
|
**Объяснение:** Максимальное пересечение в районе времени 5-6, когда активны заказы [1,10], [3,6], [4,8], [5,7]
|
||||||
Объяснение: Максимальное пересечение в районе времени 6-7
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Решение:**
|
## Решение:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -294,8 +286,8 @@ public int maxConcurrentOrders(int[][] intervals) {
|
|||||||
events.add(new int[]{interval[1], -1}); // end: -1
|
events.add(new int[]{interval[1], -1}); // end: -1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Сортируем события по времени, при равном времени сначала -1 (окончание)
|
// ИСПРАВЛЕНИЕ: При равном времени сначала обрабатываем начало заказа (+1), потом конец (-1)
|
||||||
events.sort((a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]);
|
events.sort((a, b) -> a[0] == b[0] ? b[1] - a[1] : a[0] - b[0]);
|
||||||
|
|
||||||
int maxConcurrent = 0;
|
int maxConcurrent = 0;
|
||||||
int currentConcurrent = 0;
|
int currentConcurrent = 0;
|
||||||
@@ -309,14 +301,87 @@ public int maxConcurrentOrders(int[][] intervals) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Временная сложность:** O(n log n) - сортировка событий
|
### Альтернативное решение (JavaScript):
|
||||||
**Пространственная сложность:** O(n) - список событий
|
|
||||||
|
|
||||||
### **Дополнительные вопросы:**
|
```javascript
|
||||||
|
function maxConcurrentOrders(intervals) {
|
||||||
|
if (!intervals || intervals.length === 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
1. Как найти конкретный момент времени, когда достигается максимум?
|
let events = [];
|
||||||
2. Как адаптировать алгоритм для поиска минимального количества рабочих станций?
|
|
||||||
|
|
||||||
|
// Создаем события начала и конца заказов
|
||||||
|
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: Поиск товаров в секционированном складе
|
## 🔍 Задача 5: Поиск товаров в секционированном складе
|
||||||
|
|||||||
Reference in New Issue
Block a user