← Назад к вопросам

Min и Max для слайса

2.0 Middle🔥 201 комментариев
#Основы Go

Условие

Напишите функции Min и Max для слайса целых чисел. Go не имеет встроенных функций min/max для слайсов.

Сигнатура

func Min(nums []int) (int, error)
func Max(nums []int) (int, error)

Требования

  • Вернуть ошибку для пустого слайса
  • Найти минимальный/максимальный элемент за O(n)

Пример

nums := []int{3, 1, 4, 1, 5, 9, 2, 6}
min, _ := Min(nums) // 1
max, _ := Max(nums) // 9

empty := []int{}
_, err := Min(empty) // error: empty slice

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Решение

Анализ задачи

Требования:

  • Найти минимальное и максимальное значения в слайсе
  • Обработать пустой слайс (вернуть ошибку)
  • Сложность O(n) — однопроходный алгоритм

Простое решение: пройти по слайсу один раз, сравнивая элементы.

Решение

func Min(nums []int) (int, error) {
    // Проверка на пустой слайс
    if len(nums) == 0 {
        return 0, errors.New("empty slice")
    }
    
    min := nums[0]
    for i := 1; i < len(nums); i++ {
        if nums[i] < min {
            min = nums[i]
        }
    }
    
    return min, nil
}

func Max(nums []int) (int, error) {
    // Проверка на пустой слайс
    if len(nums) == 0 {
        return 0, errors.New("empty slice")
    }
    
    max := nums[0]
    for i := 1; i < len(nums); i++ {
        if nums[i] > max {
            max = nums[i]
        }
    }
    
    return max, nil
}

Пояснения реализации

1. Проверка пустого слайса

  • len(nums) == 0 определяет пустой слайс
  • Возвращаем ошибку, а не паническое состояние

2. Инициализация

  • Берём первый элемент как начальное значение min/max
  • Это избегает необходимости использовать math.MinInt64 или math.MaxInt64

3. Итерация

  • Начинаем со второго элемента (индекс 1)
  • Сравниваем каждый элемент с текущим min/max
  • Обновляем при нахождении меньшего/большего значения

4. Сложность

  • Временная: O(n) — один проход
  • Пространственная: O(1) — только две переменные

Альтернативный вариант: одна функция для обоих значений

func MinMax(nums []int) (int, int, error) {
    if len(nums) == 0 {
        return 0, 0, errors.New("empty slice")
    }
    
    min := nums[0]
    max := nums[0]
    
    for i := 1; i < len(nums); i++ {
        if nums[i] < min {
            min = nums[i]
        }
        if nums[i] > max {
            max = nums[i]
        }
    }
    
    return min, max, nil
}

Преимущество: один проход вместо двух, экономит O(n) операций сравнения.

Использование встроенной функции sort

func Min(nums []int) (int, error) {
    if len(nums) == 0 {
        return 0, errors.New("empty slice")
    }
    
    return slices.Min(nums), nil  // Go 1.21+
}

func Max(nums []int) (int, error) {
    if len(nums) == 0 {
        return 0, errors.New("empty slice")
    }
    
    return slices.Max(nums), nil  // Go 1.21+
}

В Go 1.21+ добавлены встроенные функции в пакет slices.

Полный пример с тестированием

package main

import (
    "errors"
    "fmt"
)

func Min(nums []int) (int, error) {
    if len(nums) == 0 {
        return 0, errors.New("empty slice")
    }
    
    min := nums[0]
    for i := 1; i < len(nums); i++ {
        if nums[i] < min {
            min = nums[i]
        }
    }
    
    return min, nil
}

func Max(nums []int) (int, error) {
    if len(nums) == 0 {
        return 0, errors.New("empty slice")
    }
    
    max := nums[0]
    for i := 1; i < len(nums); i++ {
        if nums[i] > max {
            max = nums[i]
        }
    }
    
    return max, nil
}

func MinMax(nums []int) (int, int, error) {
    if len(nums) == 0 {
        return 0, 0, errors.New("empty slice")
    }
    
    min := nums[0]
    max := nums[0]
    
    for i := 1; i < len(nums); i++ {
        if nums[i] < min {
            min = nums[i]
        }
        if nums[i] > max {
            max = nums[i]
        }
    }
    
    return min, max, nil
}

func main() {
    nums := []int{3, 1, 4, 1, 5, 9, 2, 6}
    
    min, _ := Min(nums)
    max, _ := Max(nums)
    fmt.Printf("Min: %d, Max: %d\\n", min, max) // Min: 1, Max: 9
    
    // Одной функцией
    minVal, maxVal, _ := MinMax(nums)
    fmt.Printf("Min: %d, Max: %d\\n", minVal, maxVal) // Min: 1, Max: 9
    
    // Ошибка
    empty := []int{}
    _, err := Min(empty)
    fmt.Println("Error:", err) // Error: empty slice
}

Рекомендация

  • Для двух значений одновременно: используй MinMax (один проход вместо двух)
  • Если нужны отдельные функции: простая реализация выше
  • Go 1.21+: рассмотри встроенный slices.Min и slices.Max