← Назад к вопросам
Пересечение двух слайсов
1.6 Junior🔥 131 комментариев
#Основы Go#Производительность и оптимизация
Условие
На вход подаются два неупорядоченных слайса целых чисел любой длины. Напишите функцию, которая возвращает их пересечение (элементы, которые встречаются в обоих слайсах).
Сигнатура
func intersection(a, b []int) []int
Пример
Вход: a = []int{1, 2, 3, 4, 5}, b = []int{4, 5, 6, 7, 8}
Выход: []int{4, 5}
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение
Задача требует найти элементы, которые присутствуют одновременно в обоих слайсах. Ключевой момент — входные данные неупорядочены, поэтому прямое сравнение неэффективно.
Подход
Используем map (хеш-таблицу) для оптимизации:
- Создаём map из элементов первого слайса
- Итерируем по второму слайсу и ищем совпадения
- Добавляем найденные элементы в результат (учитывая дубликаты)
Реализация
func intersection(a, b []int) []int {
// Создаём map для быстрого поиска элементов первого слайса
// Ключ — число, значение — количество вхождений
mapA := make(map[int]int)
for _, num := range a {
mapA[num]++
}
var result []int
// Итерируем по второму слайсу
for _, num := range b {
// Если элемент есть в первом слайсе и его count > 0
if count, exists := mapA[num]; exists && count > 0 {
result = append(result, num)
mapA[num]-- // Уменьшаем count, чтобы не добавить дубликат
}
}
return result
}
Анализ сложности
- Временная сложность: O(n + m), где n и m — длины слайсов. Одна итерация по
a, одна поb, поиск в map — O(1). - Пространственная сложность: O(min(n, m)) — размер map и результата.
Пример работы
Вход: a = {1, 2, 3, 4, 5}, b = {4, 5, 6, 7, 8}
1. Создаём map из a: {1:1, 2:1, 3:1, 4:1, 5:1}
2. Итерируем по b:
- 4 → есть в map (count=1) → добавляем в result, count становится 0
- 5 → есть в map (count=1) → добавляем в result, count становится 0
- 6, 7, 8 → нет в map
3. Результат: {4, 5}
Альтернативный подход (для упорядоченных слайсов)
Если бы слайсы были отсортированы, можно было бы использовать two-pointers с O(n + m) временем и O(1) доп. памятью:
func intersectionSorted(a, b []int) []int {
var result []int
i, j := 0, 0
for i < len(a) && j < len(b) {
if a[i] < b[j] {
i++
} else if a[i] > b[j] {
j++
} else {
result = append(result, a[i])
i++
j++
}
}
return result
}
Но для неупорядоченных данных первый подход с map — оптимален и практичен.