JavaScript 不使用临时变量交换两个数字
给定两个变量x和y,不使用第三个变量交换这两个变量。

方法1(使用算术运算符):
示例1: 将想法是在两个给定的数中获取一个总和。然后可以使用总和和从总和中减去的结果进行交换。
JavaScript
<script>
// Javascript program to swap two
// numbers without using temporary
// variable
let x = 10, y = 5;
console.log("Before Swapping: x = " +
x + ", y = " + y);
// Code to swap 'x' and 'y'
// x now becomes 15
x = x + y;
// y becomes 10
y = x - y;
// x becomes 5
x = x - y;
console.log("After Swapping: x = " +
x + ", y = " + y);
</script>
输出:
Before Swapping: x = 10, y = 5
After Swapping: x = 5, y = 10
时间复杂度: O(1)。
辅助空间: O(1)。
示例2: 乘法和除法也可以用于交换。
Javascript
<script>
// Javascript program to swap two numbers
// without using a temporary variable
var x = 10;
var y = 5;
console.log("Before swapping:" + " x = " +
x + ", y = " + y);
// Code to swap 'x' and 'y'
x = x * y; // x now becomes 50
y = x / y; // y becomes 10
x = x / y; // x becomes 5
console.log("After swapping:" + " x = " +
x + ", y = " + y);
</script>
输出:
Before Swapping: x = 10, y = 5
After Swapping: x = 5, y = 10
时间复杂度: O(1)。
辅助空间: O(1)。
方法2(使用位操作异或):
可以使用位操作异或来交换两个变量。两个数字x和y的异或运算返回一个数字,该数字的比特位与x和y的比特位有所不同的地方全部设置为1。例如,10(二进制为1010)和5(二进制为0101)的异或结果是1111,7(二进制为0111)和5(二进制为0101)的异或结果为0010。
示例:
下面是一个示例,用于演示使用位操作异或方法交换两个数字:
Javascript
<script>
// Javascript code to swap using XOR
let x = 10, y = 5;
console.log("Before Swapping: x =" +
x + ", y=" + y);
// Code to swap 'x' (1010) and 'y' (0101)
x = x ^ y; // x now becomes 15 (1111)
y = x ^ y; // y becomes 10 (1010)
x = x ^ y; // x becomes 5 (0101)
console.log("After Swapping: x =" +
x + ", y=" + y);
</script>
输出:
Before Swapping: x = 10, y = 5
After Swapping: x = 5, y = 10
时间复杂度: O(1)。
辅助空间: O(1)。
上述方法的问题:
1: 基于乘法和除法的方法在其中一个数为0时无效,因为无论另一个数是多少,乘积都将为0。
2: 两种算术解决方案都可能导致算术溢出。如果x和y太大,加法和乘法可能超出整数范围。
3: 当我们使用指针指向变量并进行一个交换函数时,当两个指针指向同一个变量时,所有上述方法都会失败。让我们看看在这种情况下会发生什么,如果两个指针都指向同一个变量。
// Bitwise XOR based method
x = x ^ x; // x becomes 0
x = x ^ x; // x remains 0
x = x ^ x; // x remains 0
// Arithmetic based method
x = x + x; // x becomes 2x
x = x - x; // x becomes 0
x = x - x; // x remains 0
示例1: 来看下面的程序:
JavaScript
<script>
function swap(xp, yp) {
xp[0] = xp[0] ^ yp[0];
yp[0] = xp[0] ^ yp[0];
xp[0] = xp[0] ^ yp[0];
}
// Driver code
let x = [10];
console.log("Before swap(&x, &x): x = "
+ x[0]);
// Calling Swap Function
swap(x, x);
console.log("After swap(&x, &x): x = "
+ x[0]);
</script>
输出:
Before swap(&x, &x): x = 10
After swap(&x, &x): x = 0
时间复杂度: O(1)。
辅助空间: O(1)。
示例 2: 在许多标准算法中可能需要将变量与自身交换。例如,请参见 这个 快速排序的 实现中可能会进行变量与自身的交换。可以通过在交换之前添加条件来避免上述问题。
Javascript
<script>
function swap(xp, yp) {
// Check if the two addresses are the same
if (xp == yp)
return;
xp[0] = xp[0] + yp[0];
yp[0] = xp[0] - yp[0];
xp[0] = xp[0] - yp[0];
}
// Driver Code
x = 10;
console.log("Before swap(&x , &x) : x = " + x);
// Calling swap function
swap(x, x);
console.log("After swap(&x , &x) : x = " + x);
</script>
输出:
Before swap(&x , &x) : x = 10
After swap(&x , &x) : x = 10
时间复杂度: O(1)。
辅助空间: O(1)。
方法3(使用位运算符和算术运算符的混合):
思路与 方法1 讨论的相同,但使用位加法和位减法进行交换。
示例: 下面是上述方法的实现。
Javascript
<script>
function swap(a, b) {
// same as a = a + b
a = (a & b) + (a | b);
// same as b = a - b
b = a + (~b) + 1;
// same as a = a - b
a = a + (~b) + 1;
console.log("After swapping: a = " +
a + ", b = " + b);
}
let a = 5, b = 10;
console.log("Before swapping: a = " +
a + ", b = " + b);
// Function Call
swap(a, b);
</script>
输出:
Before swapping: a = 5, b = 10
After swapping: a = 10, b = 5
时间复杂度: O(1).
辅助空间: O(1),因为没有使用额外的空间。
方法4(一行表达式): 我们可以只用一行代码来交换两个数字。
- x = x ^ y ^ (y = x);
- x = x + y – (y = x);
- x = (x * y) / (y = x);
- x , y = y, x (在Python中)
示例: 下面是上述方法的实现。
Javascript
<script>
// Javascript program to swap two
// numbers without using temporary
// variable
let x = 10, y = 5;
console.log("Before Swapping: x = " + x + ", y = " + y);
// Code to swap 'x' and 'y'
x = (x * y)/(x = y);
console.log("After Swapping: x = " + x + ", y = " + y);
</script>
输出:
Before Swapping: x = 10, y = 5
After Swapping: x = 10, y = 5
时间复杂度: O(1).
辅助空间: O(1).
极客教程