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

Обмен значениями двух переменных без третьей переменной

1.0 Junior🔥 201 комментариев
#Основы Java

Условие

Напишите программу на Java для того, чтобы поменять местами значения, хранящиеся в двух переменных, без использования третьей (временной) переменной.

Пример

int a = 5;
int b = 10;
// После обмена:
// a = 10
// b = 5

Подсказка

Можно использовать арифметические операции или побитовый XOR.

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

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

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

Подход

Используем арифметические операции для обмена значений без вспомогательной переменной. При сложении и вычитании сохраняем информацию о обеих значениях в одной переменной.

Решение

public class SwapVariables {
    /**
     * Метод 1: Арифметический способ (сложение и вычитание).
     * Подходит для целых чисел любого размера.
     */
    public static void swapWithArithmetic(int[] values) {
        int a = values[0];
        int b = values[1];
        
        // Сохраняем сумму в a: a = a + b
        a = a + b;
        // b = a - b (теперь a содержит исходное a, поэтому a - b = a)
        b = a - b;
        // a = a - b (содержит исходное a + b - a = b)
        a = a - b;
        
        values[0] = a;
        values[1] = b;
    }
    
    /**
     * Метод 2: XOR битовый оператор.
     * Очень эффективен и работает с нулевыми значениями.
     */
    public static void swapWithXOR(int[] values) {
        int a = values[0];
        int b = values[1];
        
        // XOR имеет свойство: a ^ a = 0 и a ^ 0 = a
        a = a ^ b;  // a содержит XOR обеих значений
        b = a ^ b;  // b = (a ^ b) ^ b = a
        a = a ^ b;  // a = (a ^ b) ^ a = b
        
        values[0] = a;
        values[1] = b;
    }
    
    public static void main(String[] args) {
        // Пример 1: Арифметический метод
        int[] nums1 = {5, 10};
        System.out.println("До обмена (арифметика): a=" + nums1[0] + ", b=" + nums1[1]);
        swapWithArithmetic(nums1);
        System.out.println("После обмена (арифметика): a=" + nums1[0] + ", b=" + nums1[1]);
        // Выход: a=10, b=5
        
        // Пример 2: XOR метод
        int[] nums2 = {5, 10};
        System.out.println("До обмена (XOR): a=" + nums2[0] + ", b=" + nums2[1]);
        swapWithXOR(nums2);
        System.out.println("После обмена (XOR): a=" + nums2[0] + ", b=" + nums2[1]);
        // Выход: a=10, b=5
        
        // Граничный случай с нулями
        int[] nums3 = {0, 5};
        swapWithXOR(nums3);
        System.out.println("Обмен с нулём (XOR): a=" + nums3[0] + ", b=" + nums3[1]);
        // Выход: a=5, b=0
    }
}

Сложность

  • Временная сложность: O(1) — постоянное время, всего несколько операций
  • Пространственная сложность: O(1) — дополнительная память не требуется

Примеры использования

  1. Обычный обмен: a=5, b=10 → a=10, b=5
  2. С нулевыми значениями: a=0, b=5 → a=5, b=0
  3. Отрицательные числа: a=-3, b=7 → a=7, b=-3
  4. Одинаковые числа: a=5, b=5 → a=5, b=5 (остаются без изменений)

Edge cases и типичные ошибки

  1. Переполнение при сложении: Арифметический метод может привести к переполнению для больших int значений. Используйте long для большых чисел или XOR для безопасности.
  2. XOR с дубликатами: Если a == b, XOR работает корректно: a ^ a = 0.
  3. Читаемость кода: XOR и арифметические трюки более сложны для понимания. В реальном коде рекомендуется использовать временную переменную для ясности.
  4. Неопределённое поведение: Оба метода имеют чётко определённое поведение в Java, в отличие от C где порядок вычисления выражений может быть проблемой.

XOR метод предпочтителен в собеседованиях благодаря эффективности и демонстрации понимания побитовых операций.