14.03.2022, 16:07
|
Аспирант
|
|
Регистрация: 19.05.2020
Сообщений: 46
|
|
Задача про отель
Всем привет. Подскажите, верно ли я решил данную задачу?
/*
Даны даты заезда и отъезда каждого гостя.
Для каждого гостя дата заезда строго раньше даты отъезда (то есть каждый гость останавливается хотя бы на одну ночь).
В пределах одного дня считается, что сначала старые гости выезжают, а затем въезжают новые. Найти максимальное число постояльцев, которые одновременно проживали в гостинице (считаем, что измерение количества постояльцев происходит в конце дня).
*/
const dates = [
[1, 2],
[1, 3],
[2, 4],
[2, 3],
]
const f = (arr) => {
let acc = 0;
let arrivalDate = arr.reduce((accumulator, currentValue) => {
let key = currentValue[0]
if (accumulator[key]) {
accumulator[key] += 1
} else {
accumulator[key] = 1
}
return accumulator
}, {});
let departureDate = arr.reduce((accumulator, currentValue) => {
let key = currentValue[1]
if (accumulator[key]) {
accumulator[key] += 1
} else {
accumulator[key] = 1
}
return accumulator
}, {});
for (let i = 0; i < arr.length; i++) {
let current = arr[i];
acc -= departureDate[current[1]];
acc += arrivalDate[current[0]];
}
return acc;
}
console.log(f(dates));
|
|
14.03.2022, 16:35
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,227
|
|
Предложу такой вариант...
const dt = [
[1, 2],
[1, 3],
[2, 4],
[2, 3],
]
let min = dt[0][0]
let max = dt[0][0]
dt.forEach(el => {
min = Math.min(min, el[0])
max = Math.max(max, el[1])
})
let t = 0
for (let i = min; i <= max; i++) {
let c = 0
dt.forEach(el => {
if ((el[0] <= i) && (i < el[1])) ++c
})
alert(i + ' - ' + c)
t = Math.max(t, c)
}
alert(t)
|
|
14.03.2022, 19:07
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,123
|
|
const dt = [
[1, 2],
[1, 3],
[2, 4],
[2, 3]
]
let arr = dt.flat();
let min = Math.min(...arr);
let max = Math.max(...arr);
let t = 0;
for (let i = min; i <= max; i++) {
let c = 0;
dt.forEach(el => {
if ((el[0] <= i) && (i < el[1])) ++c
})
alert(i + ' - ' + c)
t = Math.max(t, c)
}
alert(t)
const dt = [
[1, 2],
[1, 3],
[2, 4],
[2, 3]
]
let arr = dt.map(([a, b]) => Array.from({
length: b - a
}, (_, i) => a + i)).flat().sort((a, b) => a - b);
let c = 0,
t = 0,
n;
for (let i of arr) {
if (i === n) c++;
else {
c = 1;
n = i;
}
if (c > t) t = c;
}
alert(t)
|
|
17.03.2022, 20:11
|
|
Профессор
|
|
Регистрация: 25.10.2016
Сообщений: 1,012
|
|
Сообщение от рони
|
Math.min(...arr)
|
на здоровенном массиве это свалится в переполнение стека.
----
мой вариант:
function getMaxCount(dates) {
const sortedByBegin = dates.slice().sort((a, b) => a[0] - b[0]);
const ends = dates.map(d => d[1]).sort((a, b) => a - b);
let count = 0, endPos = 0;
return sortedByBegin.reduce((max, date, i) => {
// учитываем все выезды, которые были после предыдущей проверки
while (endPos < ends.length && ends[endPos] <= date[0]) {
count--;
endPos++;
}
return Math.max(max, ++count);
}, 0);
}
alert(getMaxCount([
[1, 2],
[1, 3],
[2, 4],
[2, 3]
]));
работает за O(N * ln(N)) времени и O(N) памяти, но при этом не закладывается на максимальные даты, плюс можно применить например для отрезков, у которых начало и конец вещественные. Универсально, в общем.
если интервалы уже отсортированы по дате заезда, то вторую строку лучше переписать так
const sortedByBegin = dates;
|
|
17.03.2022, 21:33
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,123
|
|
Alexandroppolus,
|
|
|
|