Back to Miscellaneous Coding
Q20Question 20 of 52

Swap Two Numbers Without Using a Third Variable

Key Concepts
  • The arithmetic method uses addition then two subtractions: a=a+b, b=a-b, a=a-b to swap values
  • The XOR method uses three XOR operations: a^=b, b^=a, a^=b, exploiting the fact that x^x=0 and x^0=x
  • The arithmetic method can overflow in the intermediate sum, though modular arithmetic corrects the final result
  • Both methods break under aliasing: swapping a variable with itself (same memory location) zeroes out the value
  • In production, a temporary variable is preferred because it is clearer, equally fast, and has no edge-case surprises
  • The real lesson is reversible operations, not avoiding a temporary variable

Definition

Combine and reverse with add-subtract or XOR three times, and the two values trade places with no temporary.
  • Arithmetic swap – sets a to a+b, then b to a-b (which is the original a), then a to a-b (which is the original b), using addition and subtraction as reversible operations.
  • XOR swap – sets a to a^b, then b to a^b (which is the original a), then a to a^b (which is the original b), using the properties x^x=0 and x^0=x.
  • Aliasing danger – both methods fail if a and b refer to the same memory location, because the first operation would zero it out.
  • Production recommendation – a temporary variable is preferred because the compiler optimizes it equally well, and it has no overflow or aliasing edge cases.

Imagine Rajesh and Priya each hold a sealed envelope of cash at the National Bank of India counter, and the clerk must swap the envelopes but has no spare slot on the desk. Using a clever accounting trick, the clerk combines both amounts and then subtracts back, so by the end each person holds what the other had, without ever needing an extra empty slot.

Understanding the Concepts

What is the problem?

Given two integer variables a and b, swap their values without declaring a third temporary variable. This is a classic interview exercise that tests understanding of arithmetic properties and bitwise operations.

At the National Bank of India, think of it as swapping the balances of two holding accounts in a single ledger pass without using a staging account.

JAVA
package com.bank.core;

public class SwapDemo {
    public static void main(String[] args) {
        int a = 1000;  // Rajesh's amount
        int b = 250;   // Priya's amount
        System.out.println("Before: a=" + a + ", b=" + b);

        // Swap without temp
        a = a + b;     // a = 1250
        b = a - b;     // b = 1000 (original a)
        a = a - b;     // a = 250  (original b)

        System.out.println("After:  a=" + a + ", b=" + b);
    }
}
TEXT
Before: a=1000, b=250
After:  a=250, b=1000

How does the arithmetic method work?

The arithmetic method uses addition and subtraction. Step 1: a = a + b stores the sum in a. Step 2: b = a - b subtracts the original b from the sum, leaving b with the original a. Step 3: a = a - b subtracts the new b (original a) from the sum, leaving a with the original b.

The key insight is that addition and subtraction are inverse operations, so combining and then separating recovers both original values.

JAVA
package com.bank.core;

public class ArithmeticSwap {
    public static void swap(int[] arr, int i, int j) {
        if (i == j) return;  // guard against aliasing
        arr[i] = arr[i] + arr[j];  // sum
        arr[j] = arr[i] - arr[j];  // original arr[i]
        arr[i] = arr[i] - arr[j];  // original arr[j]
    }

    public static void main(String[] args) {
        int[] accounts = {50000, 75000, 30000};
        System.out.println("Before: " + java.util.Arrays.toString(accounts));
        swap(accounts, 0, 2);
        System.out.println("After:  " + java.util.Arrays.toString(accounts));
    }
}
TEXT
Before: [50000, 75000, 30000]
After:  [30000, 75000, 50000]

How does the XOR method work?

Exclusive-or has two useful properties: x ^ x = 0 (a value XOR itself is zero) and x ^ 0 = x (a value XOR zero is itself). The three steps are a ^= b, b ^= a, a ^= b.

After step 1, a holds the combined bits. Step 2 cancels the original b bits, leaving b with the original a. Step 3 cancels the original a bits, leaving a with the original b. XOR never overflows because it operates on bits, not numeric magnitude.

JAVA
package com.bank.core;

public class XorSwap {
    public static void swap(int[] arr, int i, int j) {
        if (i == j) return;  // guard against aliasing
        arr[i] ^= arr[j];   // combined bits
        arr[j] ^= arr[i];   // original arr[i]
        arr[i] ^= arr[j];   // original arr[j]
    }

    public static void main(String[] args) {
        int[] amounts = {1000, 250};
        System.out.println("Before: " + java.util.Arrays.toString(amounts));
        swap(amounts, 0, 1);
        System.out.println("After:  " + java.util.Arrays.toString(amounts));
    }
}
TEXT
Before: [1000, 250]
After:  [250, 1000]

What is the overflow danger in the arithmetic method?

If both values are large, a + b can exceed Integer.MAX_VALUE and wrap around. For fixed-width integers in Java, the final result is still correct because the later subtractions are exact inverse operations in modular arithmetic. However, the intermediate value is meaningless, which alarms code reviewers.

JAVA
package com.bank.core;

public class OverflowSwap {
    public static void main(String[] args) {
        int a = Integer.MAX_VALUE;  // 2147483647
        int b = 1;
        System.out.println("Before: a=" + a + ", b=" + b);

        a = a + b;  // overflows to -2147483648 (Integer.MIN_VALUE)
        System.out.println("Intermediate a (overflowed): " + a);
        b = a - b;  // 2147483647 (original a, correct!)
        a = a - b;  // 1 (original b, correct!)

        System.out.println("After: a=" + a + ", b=" + b);
    }
}
TEXT
Before: a=2147483647, b=1
Intermediate a (overflowed): -2147483648
After: a=1, b=2147483647

What is the aliasing danger?

Both methods break if the two variables are the same memory location. If you XOR a variable with itself, the first operation sets it to zero, and the remaining operations keep it at zero. The value is permanently lost.

JAVA
package com.bank.core;

public class AliasingBug {
    public static void main(String[] args) {
        int[] arr = {500};
        System.out.println("Before: " + arr[0]);

        // WRONG: swapping index 0 with itself
        int i = 0, j = 0;
        arr[i] ^= arr[j];  // arr[0] = 500 ^ 500 = 0
        arr[j] ^= arr[i];  // arr[0] = 0 ^ 0 = 0
        arr[i] ^= arr[j];  // arr[0] = 0 ^ 0 = 0

        System.out.println("After (value lost!): " + arr[0]);
    }
}
TEXT
Before: 500
After (value lost!): 0

How is arithmetic swap different from XOR swap?

| Property | Arithmetic (add/sub) | XOR (^) |
|----------|---------------------|---------|
| Overflow risk | Yes, intermediate overflows | No, bit-level operation |
| Works on floats | Yes | No, XOR is integer-only |
| Aliasing risk | Yes (zeroes value) | Yes (zeroes value) |
| Readability | Moderate | Low |
| Final correctness despite overflow | Yes (modular arithmetic) | N/A |

JAVA
// Arithmetic: works on double (no XOR for double)
double a = 1.5, b = 2.5;
a = a + b;  b = a - b;  a = a - b;
// a=2.5, b=1.5

// XOR: integers only
int x = 10, y = 20;
x ^= y;  y ^= x;  x ^= y;
// x=20, y=10

Why should you use a temporary variable in production?

A temporary variable is equally fast after compilation, far more readable, and has no overflow or aliasing edge cases. The JVM optimizes the temporary away or uses a register. The no-temporary trick is an interview curiosity, not a production practice.

JAVA
package com.bank.core;

public class TempSwap {
    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void main(String[] args) {
        int[] balances = {50000, 75000};
        System.out.println("Before: " + java.util.Arrays.toString(balances));
        swap(balances, 0, 1);
        System.out.println("After:  " + java.util.Arrays.toString(balances));
    }
}
TEXT
Before: [50000, 75000]
After:  [75000, 50000]

What should a senior engineer know?

  • Reversible operations. The real lesson is that addition/subtraction and XOR are reversible (invertible) operations, which is the mathematical foundation. This concept appears in cryptography, error correction, and other domains.
  • Compiler optimization. Modern compilers and the JVM often use register renaming or instruction reordering to swap values without an explicit temporary, so the temporary-variable version compiles to equally efficient code.
  • Array-based swaps. When swapping elements in an array (as in sorting), always guard if (i == j) return; to prevent the aliasing bug.
  • BigDecimal swap. For money, you would use a temporary BigDecimal variable, not arithmetic tricks, because BigDecimal does not support XOR and the readability cost is even higher.
JAVA
import java.math.BigDecimal;

BigDecimal temp = balanceA;
balanceA = balanceB;
balanceB = temp;
// Clear, safe, no surprises

Visual Overview

DIAGRAM
  Arithmetic Swap (a=1000, b=250):

  Step 1: a = a + b
  ┌──────┐  ┌──────┐
  │ 1000 │  │  250 │
  └──────┘  └──────┘
      a = 1250      b = 250

  Step 2: b = a - b
      a = 1250      b = 1250 - 250 = 1000

  Step 3: a = a - b
      a = 1250 - 1000 = 250    b = 1000

  Result: a=250, b=1000  (swapped)
TEXT
  XOR Swap (a=1000, b=250):

  Step 1: a = a ^ b
  a = 1000 ^ 250 = 786  (combined bits)
  b = 250

  Step 2: b = a ^ b
  b = 786 ^ 250 = 1000  (original a)
  a = 786

  Step 3: a = a ^ b
  a = 786 ^ 1000 = 250  (original b)
  b = 1000

  Result: a=250, b=1000  (swapped)

Key Takeaway

Swapping two numbers without a temporary variable can be done two ways. The arithmetic method sets a to a plus b, then b to a minus b (which recovers the original a), then a to a minus b (which recovers the original b). The XOR method uses three exclusive-or operations, relying on the facts that a value XOR itself is zero and a value XOR zero is itself.

Both methods have real dangers. The arithmetic method can overflow in the intermediate sum, though for Java's fixed-width integers the final result is still correct because the subtractions are exact inverses in modular arithmetic. The XOR method never overflows, but both methods break under aliasing: when two variables point to the same memory location, the first operation zeroes the value and it is permanently lost.

The honest production recommendation is that a plain temporary variable is the right choice. After compilation, the JVM optimizes it equally well using register renaming, and it has none of the overflow or aliasing surprises. The no-temporary trick is an interview exercise about reversible operations, not a production best practice.

In the banking context at the National Bank of India, when swapping elements during a ledger reordering pass, I always guard with if (i == j) return to prevent the aliasing bug, and I use a temporary variable because the readability and safety matter more than saving one local variable slot.

Remember one sentence: XOR and add-subtract swap values through reversible operations, but in production a temporary variable is clearer, equally fast, and free of aliasing and overflow traps.

---

Share
Use ← → arrow keys to navigate