← Назад к вопросам
Развернуть слова в строке
2.2 Middle🔥 181 комментариев
#Основы Go
Условие
Дана строка s. Разверните порядок слов в строке. Слова разделены пробелами. Лишние пробелы в начале, конце и между словами нужно убрать.
Сигнатура
func reverseWords(s string) string
Примеры
Вход: "the sky is blue"
Выход: "blue is sky the"
Вход: " hello world "
Выход: "world hello"
Вход: "a good example"
Выход: "example good a"
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение
Min и Max — это базовые операции для работы со слайсами. Go в отличие от Python/JavaScript не имеет встроенных функций, поэтому нужно реализовать самостоятельно.
Подход
- Проверить, что слайс не пустой
- Инициализировать результат первым элементом
- Пройти по остальным элементам, сравнивая
Реализация
package main
import (
"errors"
"fmt"
)
var ErrEmptySlice = errors.New("empty slice")
func Min(nums []int) (int, error) {
if len(nums) == 0 {
return 0, ErrEmptySlice
}
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, ErrEmptySlice
}
max := nums[0]
for i := 1; i < len(nums); i++ {
if nums[i] > max {
max = nums[i]
}
}
return max, nil
}
func main() {
nums := []int{3, 1, 4, 1, 5, 9, 2, 6}
min, _ := Min(nums)
max, _ := Max(nums)
fmt.Printf("Min: %d\n", min) // 1
fmt.Printf("Max: %d\n", max) // 9
// Тест на пустом слайсе
empty := []int{}
_, err := Min(empty)
fmt.Printf("Error: %v\n", err) // empty slice
}
Анализ сложности
- Временная: O(n) — один проход по всем элементам
- Пространственная: O(1) — используем только одну переменную для результата
Альтернативный вариант с range
func Min(nums []int) (int, error) {
if len(nums) == 0 {
return 0, ErrEmptySlice
}
min := nums[0]
for _, num := range nums[1:] { // пропускаем первый
if num < min {
min = num
}
}
return min, nil
}
Generic версия (Go 1.18+)
import "cmp"
func Min[T cmp.Ordered](nums []T) (T, error) {
if len(nums) == 0 {
var zero T
return zero, ErrEmptySlice
}
min := nums[0]
for _, num := range nums[1:] {
if num < min {
min = num
}
}
return min, nil
}
func Max[T cmp.Ordered](nums []T) (T, error) {
if len(nums) == 0 {
var zero T
return zero, ErrEmptySlice
}
max := nums[0]
for _, num := range nums[1:] {
if num > max {
max = num
}
}
return max, nil
}
func main() {
// Работает с int
nums := []int{3, 1, 4, 1, 5}
min, _ := Min(nums)
fmt.Println(min) // 1
// Работает с float64
floats := []float64{3.14, 1.41, 2.71}
maxF, _ := Max(floats)
fmt.Println(maxF) // 3.14
// Работает со строками
strs := []string{"apple", "zebra", "banana"}
minS, _ := Min(strs)
fmt.Println(minS) // apple
}
Полный код с примерами
package main
import (
"errors"
"fmt"
)
var ErrEmptySlice = errors.New("empty slice")
func Min(nums []int) (int, error) {
if len(nums) == 0 {
return 0, ErrEmptySlice
}
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, ErrEmptySlice
}
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, ErrEmptySlice
}
min, max := nums[0], 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() {
// Пример 1: базовое использование
fmt.Println("=== Пример 1: базовое использование ===")
nums := []int{3, 1, 4, 1, 5, 9, 2, 6}
min, err := Min(nums)
if err != nil {
fmt.Printf("Min error: %v\n", err)
} else {
fmt.Printf("Min: %d\n", min) // 1
}
max, err := Max(nums)
if err != nil {
fmt.Printf("Max error: %v\n", err)
} else {
fmt.Printf("Max: %d\n", max) // 9
}
// Пример 2: пустой слайс
fmt.Println("\n=== Пример 2: пустой слайс ===")
empty := []int{}
_, err = Min(empty)
fmt.Printf("Min on empty: %v\n", err) // empty slice
// Пример 3: один элемент
fmt.Println("\n=== Пример 3: один элемент ===")
one := []int{42}
min, _ = Min(one)
max, _ = Max(one)
fmt.Printf("Min: %d, Max: %d\n", min, max) // 42, 42
// Пример 4: отрицательные числа
fmt.Println("\n=== Пример 4: отрицательные числа ===")
negative := []int{-5, 0, 5, -10, 10}
min, _ = Min(negative)
max, _ = Max(negative)
fmt.Printf("Min: %d, Max: %d\n", min, max) // -10, 10
// Пример 5: одновременно Min и Max
fmt.Println("\n=== Пример 5: одновременно Min и Max ===")
minVal, maxVal, _ := MinMax(nums)
fmt.Printf("Min: %d, Max: %d\n", minVal, maxVal) // 1, 9
}
Оптимизация: найти Min и Max одновременно
func MinMax(nums []int) (int, int, error) {
if len(nums) == 0 {
return 0, 0, ErrEmptySlice
}
min, max := nums[0], nums[0]
// Оптимизация: сравниваем попарно
// Это уменьшает количество сравнений с 2n до 3n/2
for i := 1; i < len(nums); i += 2 {
var a, b int
a = nums[i]
if i+1 < len(nums) {
b = nums[i+1]
} else {
b = a
}
// Сначала сравниваем a и b
if a < b {
if a < min {
min = a
}
if b > max {
max = b
}
} else {
if b < min {
min = b
}
if a > max {
max = a
}
}
}
return min, max, nil
}
Производительность
Для слайса из 1000 элементов:
Отдельные Min() и Max(): 2000 сравнений
Одновременно MinMax(): 1000 сравнений
Оптимизированный MinMax(): 1500 сравнений
Выигрыш: ~25-33% для больших слайсов
Сравнение с встроенными функциями других языков
Python:
min(nums) # встроенная функция
max(nums) # встроенная функция
Go:
min, _ := Min(nums) // нужно реализовать
max, _ := Max(nums) // нужно реализовать
Go 1.21+:
min(nums...) // встроенная функция (но требует распаковки слайса)
max(nums...) // встроенная функция
Обработка ошибок
Вариант 1: Вернуть zero value + error
func Min(nums []int) (int, error) {
if len(nums) == 0 {
return 0, errors.New("empty slice")
}
// ...
}
Вариант 2: Panic (менее идиоматично)
func Min(nums []int) int {
if len(nums) == 0 {
panic("empty slice")
}
// ...
}
Вариант 3: Использовать sentinel value
func Min(nums []int) int {
if len(nums) == 0 {
return math.MaxInt
}
// ...
}
Ключевые выводы
- O(n) — оптимально для неотсортированного слайса
- Проверка пустого слайса обязательна
- Generics позволяют писать универсальные функции
- Оптимизация: найти min и max одновременно на ~33% быстрее
- Встроенные функции Go 1.21+ улучшают ситуацию
Это базовые функции, которые должны быть в утилитарной библиотеке проекта.