Цель: попрактиковаться в обработке массивов, сортировке и группировке данных.
Set
из массива, а затем снова преобразовать его в массив.current + 1
).start-end
.const range = (numbers) => {
// Шаг 1: Обработка пустого массива.
// Если массив пуст, по условию возвращаем пустую строку.
if (numbers.length === 0) return '';
// Шаг 2: Подготовка данных.
// Создаем `Set` из массива, чтобы автоматически удалить дубликаты.
// `Array.from` преобразует `Set` обратно в массив.
// `.sort((a, b) => a - b)` сортирует числа в порядке возрастания.
const sortedUniqNumbers = Array.from(new Set(numbers))
.sort((a, b) => a - b);
// Шаг 3: Инициализация переменных.
// `ranges` — массив для хранения итоговых строк (чисел и диапазонов).
const ranges = [];
// `start` — хранит начальное число текущего диапазона.
let start = sortedUniqNumbers[0];
// `prev` — хранит предыдущее число для проверки последовательности.
let prev = start;
// Шаг 4: Итерация по массиву для поиска диапазонов.
// Начинаем со второго элемента (i=1) и идем до конца массива (включая "виртуальный" элемент после последнего).
// Это позволяет обработать последний диапазон без дополнительного кода после цикла.
for (let i = 1; i <= sortedUniqNumbers.length; i++) {
// `current` — текущее рассматриваемое число.
const current = sortedUniqNumbers[i];
// Шаг 5: Проверка, продолжается ли последовательность.
// Если текущее число на 1 больше предыдущего, значит, мы все еще в диапазоне.
if (current === prev + 1) {
// Обновляем `prev` и переходим к следующему числу.
prev = current;
continue;
}
// Шаг 6: Последовательность прервалась. Формируем строку для завершенного диапазона.
// Если `start` и `prev` равны, диапазон состоял из одного числа.
if (start === prev) {
ranges.push(String(start));
}
// Если в диапазоне было два числа (например, 5, 6), они не образуют диапазон "5-6".
// Добавляем их как два отдельных числа.
else if (start + 1 === prev) {
ranges.push(String(start), String(prev));
}
// Если чисел в диапазоне три или больше, форматируем как `start-prev`.
else {
ranges.push(`${start}-${prev}`);
}
// Шаг 7: Сброс переменных для следующего потенциального диапазона.
// Новое начало — это `current`, число, которое прервало предыдущую последовательность.
start = current;
prev = current;
}
// Шаг 8: Возвращаем результат.
// Объединяем все строки из массива `ranges` в одну, разделенную запятыми.
return ranges.join(',');
};
Анализ решения:
Этот подход к решению задачи можно разбить на несколько ключевых этапов:
Обработка крайнего случая: Первым делом функция проверяет, не является ли входной массив пустым. Если это так, она немедленно возвращает пустую строку в соответствии с требованиями задачи. Это простая, но важная оптимизация, которая предотвращает выполнение лишнего кода.
Подготовка данных (Очистка и Сортировка):
Set
, которая по своей природе хранит только уникальные значения. Создание new Set(numbers)
и последующее преобразование обратно в массив с помощью Array.from()
является элегантным и эффективным способом избавиться от дубликатов..sort((a, b) => a - b)
гарантирует, что числа будут расположены в порядке возрастания, что является необходимым условием для нашего алгоритма.Итеративный поиск диапазонов:
ranges
для хранения итоговых строк, start
для отметки начала текущего диапазона и prev
для хранения предыдущего элемента.current
) с предыдущим (prev
).current
на единицу больше prev
, это означает, что последовательность продолжается. Мы просто обновляем prev
и переходим к следующей итерации.start
и prev
равны, значит, это было одиночное число.start + 1 === prev
), мы добавляем их по отдельности, а не как диапазон (например, 5,6
вместо 5-6
).start-prev
.Сборка результата: После завершения цикла массив ranges
содержит все необходимые строки ('0-5'
, '8'
, '9'
, '11'
). Метод join(',')
объединяет их в финальную строку, которую и возвращает функция.
.sort()
). Сам цикл проходит по массиву один раз, что дает O(N), но сортировка доминирует.ranges
с результатами. В худшем случае (когда нет диапазонов) оба массива будут иметь размер, сравнимый с размером исходного массива.Напишите функцию range
, которая принимает массив целых чисел и возвращает строку, представляющую отсортированные и сгруппированные диапазоны этих чисел.
Числа в строке должны быть отсортированы по возрастанию. Последовательные числа должны быть сгруппированы в диапазон, например, 1, 2, 3, 4
превращается в 1-4
. Если число не входит ни в какой диапазон, оно остается как есть.
range([1, 4, 5, 2, 3, 9, 8, 11, 0]);
// Вернет: '0-5,8,9,11'
range([-1, 0, 1, 5, 6]);
// Вернет: '-1-1,5,6'
range([1, 3, 5]);
// Вернет: '1,3,5'
range
.Цель: попрактиковаться в обработке массивов, сортировке и группировке данных.
Set
из массива, а затем снова преобразовать его в массив.current + 1
).start-end
.const range = (numbers) => {
// Шаг 1: Обработка пустого массива.
// Если массив пуст, по условию возвращаем пустую строку.
if (numbers.length === 0) return '';
// Шаг 2: Подготовка данных.
// Создаем `Set` из массива, чтобы автоматически удалить дубликаты.
// `Array.from` преобразует `Set` обратно в массив.
// `.sort((a, b) => a - b)` сортирует числа в порядке возрастания.
const sortedUniqNumbers = Array.from(new Set(numbers))
.sort((a, b) => a - b);
// Шаг 3: Инициализация переменных.
// `ranges` — массив для хранения итоговых строк (чисел и диапазонов).
const ranges = [];
// `start` — хранит начальное число текущего диапазона.
let start = sortedUniqNumbers[0];
// `prev` — хранит предыдущее число для проверки последовательности.
let prev = start;
// Шаг 4: Итерация по массиву для поиска диапазонов.
// Начинаем со второго элемента (i=1) и идем до конца массива (включая "виртуальный" элемент после последнего).
// Это позволяет обработать последний диапазон без дополнительного кода после цикла.
for (let i = 1; i <= sortedUniqNumbers.length; i++) {
// `current` — текущее рассматриваемое число.
const current = sortedUniqNumbers[i];
// Шаг 5: Проверка, продолжается ли последовательность.
// Если текущее число на 1 больше предыдущего, значит, мы все еще в диапазоне.
if (current === prev + 1) {
// Обновляем `prev` и переходим к следующему числу.
prev = current;
continue;
}
// Шаг 6: Последовательность прервалась. Формируем строку для завершенного диапазона.
// Если `start` и `prev` равны, диапазон состоял из одного числа.
if (start === prev) {
ranges.push(String(start));
}
// Если в диапазоне было два числа (например, 5, 6), они не образуют диапазон "5-6".
// Добавляем их как два отдельных числа.
else if (start + 1 === prev) {
ranges.push(String(start), String(prev));
}
// Если чисел в диапазоне три или больше, форматируем как `start-prev`.
else {
ranges.push(`${start}-${prev}`);
}
// Шаг 7: Сброс переменных для следующего потенциального диапазона.
// Новое начало — это `current`, число, которое прервало предыдущую последовательность.
start = current;
prev = current;
}
// Шаг 8: Возвращаем результат.
// Объединяем все строки из массива `ranges` в одну, разделенную запятыми.
return ranges.join(',');
};
Анализ решения:
Этот подход к решению задачи можно разбить на несколько ключевых этапов:
Обработка крайнего случая: Первым делом функция проверяет, не является ли входной массив пустым. Если это так, она немедленно возвращает пустую строку в соответствии с требованиями задачи. Это простая, но важная оптимизация, которая предотвращает выполнение лишнего кода.
Подготовка данных (Очистка и Сортировка):
Set
, которая по своей природе хранит только уникальные значения. Создание new Set(numbers)
и последующее преобразование обратно в массив с помощью Array.from()
является элегантным и эффективным способом избавиться от дубликатов..sort((a, b) => a - b)
гарантирует, что числа будут расположены в порядке возрастания, что является необходимым условием для нашего алгоритма.Итеративный поиск диапазонов:
ranges
для хранения итоговых строк, start
для отметки начала текущего диапазона и prev
для хранения предыдущего элемента.current
) с предыдущим (prev
).current
на единицу больше prev
, это означает, что последовательность продолжается. Мы просто обновляем prev
и переходим к следующей итерации.start
и prev
равны, значит, это было одиночное число.start + 1 === prev
), мы добавляем их по отдельности, а не как диапазон (например, 5,6
вместо 5-6
).start-prev
.Сборка результата: После завершения цикла массив ranges
содержит все необходимые строки ('0-5'
, '8'
, '9'
, '11'
). Метод join(',')
объединяет их в финальную строку, которую и возвращает функция.
.sort()
). Сам цикл проходит по массиву один раз, что дает O(N), но сортировка доминирует.ranges
с результатами. В худшем случае (когда нет диапазонов) оба массива будут иметь размер, сравнимый с размером исходного массива.Напишите функцию range
, которая принимает массив целых чисел и возвращает строку, представляющую отсортированные и сгруппированные диапазоны этих чисел.
Числа в строке должны быть отсортированы по возрастанию. Последовательные числа должны быть сгруппированы в диапазон, например, 1, 2, 3, 4
превращается в 1-4
. Если число не входит ни в какой диапазон, оно остается как есть.
range([1, 4, 5, 2, 3, 9, 8, 11, 0]);
// Вернет: '0-5,8,9,11'
range([-1, 0, 1, 5, 6]);
// Вернет: '-1-1,5,6'
range([1, 3, 5]);
// Вернет: '1,3,5'
range
.Редактор кода намеренно скрыт на мобильном.
Поверь, так лучше: я оберегаю тебя от искушения писать код в неидеальных условиях. Маленький экран и виртуальная клавиатура — не лучшие помощники для программиста.
📖 Сейчас: Изучи задачу, продумай решение. Действуй как стратег.
💻 Потом: Сядь за компьютер, открой сайт и реализуй все идеи с комфортом. Действуй как код-джедай!