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

Как развернуть строку задом наперед?

1.7 Middle🔥 161 комментариев
#JavaScript Core

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

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

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

Разворот строки: все методы

Это базовый вопрос для проверки знания строковых методов и алгоритмического мышления. Покажу 7 способов от простого к сложному.

1. Встроенный метод split + reverse + join

Самый популярный и читаемый способ:

const str = "Hello";
const reversed = str.split("").reverse().join("");
console.log(reversed); // "olleH"

Как это работает:

  • split("") - превращает строку в массив символов: ["H","e","l","l","o"]
  • reverse() - разворачивает массив: ["o","l","l","e","H"]
  • join("") - объединяет в строку: "olleH"

Это стандартное решение. Используй именно его в реальном коде.

2. Использование spread оператора

Современный вариант:

const str = "Hello";
const reversed = [...str].reverse().join("");
console.log(reversed); // "olleH"

Преимущество: более явно показывает, что мы работаем с символами.

3. Цикл for в обратном направлении

function reverseString(str) {
  let reversed = "";
  for (let i = str.length - 1; i >= 0; i--) {
    reversed += str[i];
  }
  return reversed;
}

console.log(reverseString("Hello")); // "olleH"

Когда использовать: когда интервьюер хочет увидеть понимание алгоритма, а не знание встроенных методов.

4. Рекурсивный подход

function reverseString(str) {
  // Базовый случай
  if (str.length === 0) return "";
  if (str.length === 1) return str;
  
  // Рекурсивный случай
  return reverseString(str.substring(1)) + str[0];
}

console.log(reverseString("Hello")); // "olleH"

Как работает:

  • reverseString("ello") + "H"
  • reverseString("llo") + "e" + "H"
  • reverseString("lo") + "l" + "e" + "H"
  • ... и так далее

Внимание: может быть медленным для больших строк (O(n^2)).

5. Рекурсия с аккумулятором (оптимизированная)

function reverseString(str, acc = "") {
  if (str.length === 0) return acc;
  return reverseString(str.substring(1), str[0] + acc);
}

console.log(reverseString("Hello")); // "olleH"

Это быстрее, так как не создаёт новые строки постоянно.

6. Использование reduce

Функциональный подход:

const str = "Hello";
const reversed = str.split("").reduce((rev, char) => char + rev, "");
console.log(reversed); // "olleH"

Как работает:

Начало: acc = ""
"H": "H" + "" = "H"
"e": "e" + "H" = "eH"
"l": "l" + "eH" = "leH"
"l": "l" + "leH" = "lleH"
"o": "o" + "lleH" = "olleH"

7. Использование Array.from

const str = "Hello";
const reversed = Array.from(str).reverse().join("");
console.log(reversed); // "olleH"

Работает как split(""), но более явно.

Сравнение производительности

const str = "a".repeat(100000); // Большая строка

// 1. split + reverse + join - БЫСТРО (встроенные оптимизации)
console.time("split-reverse-join");
const r1 = str.split("").reverse().join("");
console.timeEnd("split-reverse-join"); // ~5ms

// 2. Цикл for - БЫСТРО
console.time("for loop");
let r2 = "";
for (let i = str.length - 1; i >= 0; i--) {
  r2 += str[i];
}
console.timeEnd("for loop"); // ~10ms (медленнее из-за конкатенации)

// 3. Reduce - МЕДЛЕННО
console.time("reduce");
const r3 = str.split("").reduce((acc, c) => c + acc, "");
console.timeEnd("reduce"); // ~20ms

// 4. Рекурсия - ОЧЕНЬ МЕДЛЕННО
console.time("recursion");
function rev(s) {
  return s.length === 0 ? "" : rev(s.substring(1)) + s[0];
}
const r4 = rev(str);
console.timeEnd("recursion"); // ~1000ms+ (и может быть stack overflow!)

Важный момент: Unicode и многобайтовые символы

Простое разворачивание может сломать emoji и специальные символы:

// Проблема с emoji
const emoji = "Hello 👋 World";
console.log(emoji.split("").reverse().join(""));
// "dlroW 🏻 olleH" - emoji сломан!

// Правильное решение - использовать Array.from или spread
const correct = [...emoji].reverse().join("");
// Но даже это может не работать для сложных emoji

// Самое надёжное - использовать Intl API или библиотеку
function reverseString(str) {
  return Array.from(str).reverse().join("");
}

Практический пример для собеседования

// Вопрос: "Разверни строку"
// Ответ 1: Простое решение
function reverse1(str) {
  return str.split("").reverse().join("");
}

// Интервьюер: "Хорошо. Как это работает?"
// Ответ: split разбивает на массив, reverse разворачивает, join объединяет

// Интервьюер: "А без встроенных методов?"
// Ответ 2: Цикл
function reverse2(str) {
  let result = "";
  for (let i = str.length - 1; i >= 0; i--) {
    result += str[i];
  }
  return result;
}

// Интервьюер: "А сложность какая?"
// Ответ: O(n) по времени, O(n) по памяти (для нового результата)

// Интервьюер: "Если бы нужно было развернуть на месте?"
// Ответ 3: В массиве можно O(1) памяти (swap)
function reverseArray(arr) {
  let left = 0, right = arr.length - 1;
  while (left < right) {
    [arr[left], arr[right]] = [arr[right], arr[left]];
    left++;
    right--;
  }
  return arr;
}

Вопросы, которые могут задать

// 1. Разверни строку
reverse("hello") // "olleh"

// 2. А если строка очень большая?
// Ответ: split + reverse + join очень быстро благодаря V8

// 3. Как быть с Unicode?
// Ответ: использовать [...str] вместо split("")

// 4. Какой способ выбрать?
// Ответ: split + reverse + join (читаемо и быстро)

// 5. Сложность?
// Ответ: O(n) время, O(n) память

Чек-лист

  • Знаю 3+ способа разворота (split, цикл, рекурсия)
  • Понимаю сложность каждого способа
  • Знаю про проблемы с Unicode/emoji
  • Могу объяснить, как работает каждый способ
  • Выбираю правильный способ для контекста
Как развернуть строку задом наперед? | PrepBro