Swap two number in place without temporary variables
Problem
Write a function to swap two number in place without temporary variables.
Examples
Example 1
Input: a = 3, b = 7
Output: a = 7, b = 3
Explanation: Swapping two integer variables without a temporary variable should exchange their values.
Example 2
Input: a = 5, b = 5
Output: a = 5, b = 5
Explanation: Values are equal — swapping without a temporary variable should leave them unchanged.
Solution
Method 1 - The XOR (exclusive) trick
Intuition
XOR is a bitwise operation that acts independently on each bit. Two useful identities are:
v ^ v = 0(a value XOR itself is zero)v ^ 0 = v(a value XOR zero is the value)
When we write a = a ^ b, the result stores, for every bit position, whether a and b differed at that position (1) or not (0). If we then XOR that result back with one of the original values we can recover the other value, because:
(a ^ b) ^ b = a(sinceb ^ b = 0andx ^ 0 = x)
The three-step XOR swap works by using these identities to interleave and then restore bits:
a = a ^ b— nowaholds the bitwise differences (call this D = a^b).b = b ^ a— sinceais D, this becomesb = b ^ D = b ^ (a ^ b) = a(sobbecomes the originala).a = a ^ b— nowa = D ^ a(original)which evaluates tob(the originalb).
Because each step is bitwise and reversible, the pair (a, b) ends up swapped without allocating an extra variable. The trick only works safely for integer-like types and when you avoid the special cases below.
Approach
- If swapping the same memory location (or the same variable) do nothing — swapping in-place is a no-op.
- If the two values are equal, do nothing — XORing identical values can produce zero and lead to incorrect results when performed in-place.
- Otherwise perform three XOR operations in sequence (use
aandb):
a ^= bb ^= aa ^= b
Caveats
The XOR swap works for integer-like types but has several practical pitfalls you should guard against. Below are the main issues and short guidance.
Undefined behaviour
The compact one-liner a ^= b ^= a ^= b; is undefined behaviour in C/C++ because it modifies a more than once without intervening sequence points. Always use the explicit three-statement sequence and avoid modifying the same storage twice in a single expression.
Aliasing and equal-values
If the two operands refer to the same memory location (aliasing) or are equal, an unguarded XOR swap can produce zeroed results. Guard with if (&a == &b) return; for pointer/reference cases or if (a == b) return; for value checks.
Floating-point and non-integers
The XOR trick is a bitwise integer operation and is not suitable for floating-point or non-integer types.
Concurrency and atomicity
These swaps are not atomic. In multithreaded code use proper synchronization or hardware-supported atomic-swap operations.
Recommendation
For readable, robust production code prefer a temporary variable unless you have a specific reason to avoid one; use the XOR trick only when you understand and guard for the issues above.
Safe pattern
Prefer a guarded swap to avoid aliasing and equal-value pitfalls:
// C-style guard, works similarly in other languages (use references/pointers where available)
if (&a == &b) return; // same address — no-op
if (a == b) return; // equal values — no-op
a ^= b;
b ^= a;
a ^= b;
Bit-level example
Let a = 5 (binary 0101) and b = 3 (binary 0011):
D = a ^ b = 0101 ^ 0011 = 0110- After
a = a ^ b→a = 0110(D) - After
b = b ^ a→b = 0011 ^ 0110 = 0101(originala) - After
a = a ^ b→a = 0110 ^ 0101 = 0011(originalb)
Final values: a = 3, b = 5.
Complexity
- ⏰ Time complexity:
O(1)– A constant number of bitwise operations are performed. - 🧺 Space complexity:
O(1)– No additional storage is used.
Code
C
// Pointer-style swap using XOR. Caller passes addresses of integers.
void swapNumbers(int *a, int *b) {
if (a == b) return; // same address
if (*a == *b) return; // equal values — XOR would zero
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
C++
// Swap two integers by reference using XOR. Works for integer types.
#include <iostream>
class Solution {
public:
static void swapNumbers(int &a, int &b) {
if (&a == &b) return;
if (a == b) return;
a ^= b;
b ^= a;
a ^= b;
}
};
Go
package main
import "fmt"
// swapNumbers swaps two integer values via pointers using XOR.
func swapNumbers(a, b *int) {
if a == b {
return
}
if *a == *b {
return
}
*a ^= *b
*b ^= *a
*a ^= *b
}
func main() {
a, b := 3, 7
swapNumbers(&a, &b)
fmt.Println(a, b) // 7 3
}
Java
// Demonstration in main since Java primitives are passed by value.
class Solution {
public static void main(String[] args) {
int a = 3, b = 7;
if (a != b) {
a ^= b;
b ^= a;
a ^= b;
}
System.out.println(a + " " + b); // 7 3
}
}
Kotlin
// Demonstration in main since Kotlin primitives are value types.
fun main() {
var a = 3
var b = 7
if (a != b) {
a = a xor b
b = b xor a
a = a xor b
}
println("$a $b") // 7 3
}
Python
# Demonstration in main since Python integers are immutable and there is
# no pass-by-reference for primitives. Use local variable XOR swap.
def main() -> None:
a: int = 3
b: int = 7
if a != b:
a ^= b
b ^= a
a ^= b
print(a, b) # 7 3
if __name__ == "__main__":
main()
Rust
// Swap two integers via mutable references using XOR.
fn swap_numbers(a: &mut i32, b: &mut i32) {
if (a as *const _) == (b as *const _) { return }
if *a == *b { return }
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
fn main() {
let mut a: i32 = 3;
let mut b: i32 = 7;
swap_numbers(&mut a, &mut b);
println!("{} {}", a, b); // 7 3
}
Typescript
// Demonstration in main since TypeScript numbers are primitives (by value).
let a: number = 3;
let b: number = 7;
if (a !== b) {
a ^= b;
b ^= a;
a ^= b;
}
console.log(a, b); // 7 3
Method 2 - Addition and subtraction trick
Intuition
You can swap two numeric values using arithmetic: add them and then subtract to recover each original value in swapped positions. This uses no extra user-visible temporary variables but is vulnerable to integer overflow for fixed-width types.
Approach
- If the two variables refer to the same location (or are the same variable) do nothing — swapping a variable with itself is a no-op.
- Perform three arithmetic operations:
a = a + bb = a - b(now holds originala)a = a - b(now holds originalb)
- Use this only when you are certain the addition will not overflow the numeric type. For safety, in production use a temporary variable or a wider type when possible.
Complexity
- ⏰ Time complexity:
O(1)– Only three arithmetic operations are performed. - 🧺 Space complexity:
O(1)– No extra storage is used.
Code
C
// Pointer-style swap using addition/subtraction. Caller passes addresses.
void swapNumbers(int *a, int *b) {
if (a == b) return; // same address
// Be careful: addition may overflow for fixed-width ints.
*a = *a + *b;
*b = *a - *b; // original *a
*a = *a - *b; // original *b
}
C++
// Swap two integers by reference using addition/subtraction.
#include <iostream>
class Solution {
public:
static void swapNumbers(int &a, int &b) {
if (&a == &b) return;
// Beware of overflow for fixed-width ints
a = a + b;
b = a - b; // original a
a = a - b; // original b
}
};
Go
package main
import "fmt"
// swapNumbers swaps two integer values via pointers using addition/subtraction.
func swapNumbers(a, b *int) {
if a == b { return }
*a = *a + *b
*b = *a - *b
*a = *a - *b
}
func main() {
a, b := 3, 7
swapNumbers(&a, &b)
fmt.Println(a, b) // 7 3
}
Java
// Demonstration in main since Java primitives are passed by value.
class Solution {
public static void main(String[] args) {
int a = 3, b = 7;
// Beware of overflow for 32-bit ints in other inputs
a = a + b;
b = a - b; // original a
a = a - b; // original b
System.out.println(a + " " + b); // 7 3
}
}
Kotlin
// Demonstration in main since Kotlin primitives are value types.
func main() {
a, b := 3, 7
swapNumbers(&a, &b)
fmt.Println(a, b) // 7 3
}
y = x - y // original x
x = x - y // original y
println("$x $y") // 7 3
}
Python
# Demonstration in main for Python; Python ints are unbounded so overflow is not a concern here.
def main() -> None:
a: int = 3
b: int = 7
a = a + b
b = a - b
a = a - b
print(a, b) # 7 3
if __name__ == "__main__":
main()
Rust
// Swap two integers via mutable references using addition/subtraction.
fn swap_numbers(a: &mut i64, b: &mut i64) {
if (a as *const _) == (b as *const _) { return }
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}
fn main() {
let mut a: i64 = 3;
let mut b: i64 = 7;
swap_numbers(&mut a, &mut b);
println!("{} {}", a, b); // 7 3
}
Typescript
// Demonstration in main since TypeScript numbers are primitives (by value).
let a: number = 3;
let b: number = 7;
// Note: JS numbers are floating point; use with care for large integers.
a = a + b;
b = a - b; // original a
a = a - b; // original b
console.log(a, b); // 7 3