首先讲讲交换数组的常规写法:
创建临时变量交换数组元素
function swap(nums, a, b) {
const temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}
const list = [1,2,3,4];
swap(list, 0, 3);
console.log(list); // [4,2,3,1]
那能不能不创建临时变量去交换数组呢?
有如下方法
- 异或(^)
- 加减
- 乘除
下面分别讲一讲他们的优劣
异或运算符
function swap(nums, a, b) {
nums[a] ^= nums[b]; // nums[a] = nums[a] ^ nums[b]
nums[b] ^= nums[a]; // nums[b] = nums[b] ^ nums[a] = nums[b] ^ (nums[a] ^ nums[b]) = nums[a] ^ (nums[b] ^ nums[b]) = nums[a] ^ 0 = nums[a]
nums[a] ^= nums[b]; // nums[a] = nums[a] ^ nums[b] = (nums[a] ^ nums[b]) ^ (nums[a]) = nums[b] ^ (nums[a] ^ nums[a]) = nums[b] ^ 0 = nums[b]
}
优势:不用临时变量直接交换了数组两个元素
劣势:交换相同变量得到的结果为 0,因为 a ^ a = 0
。 如下
let arr = [1, 2];
let i = 0;
let j = 0;
swap(arr, i, j);
console.log(arr); // [0, 2]
很明显 arr 第一个元素不对了,原因 a ^ a = 0
导致的。
加法运算符
function swap(nums, a, b) {
nums[a] = nums[a] + nums[b];
nums[b] = nums[a] - nums[b];
nums[a] = nums[a] - nums[b];
}
优势:不用临时变量直接交换了数组两个元素
劣势:交换相同变量得到的结果为 0;两数相加可能数值溢出;
乘法运算符
function swap(nums, a, b) {
nums[a] = nums[a] * nums[b];
nums[b] = nums[a] / nums[b];
nums[a] = nums[a] / nums[b];
}
优势:不用临时变量直接交换了数组两个元素
劣势:交换相同变量得到的结果为 1;两数相乘可能数值溢出;
总结
看好异或运算,加法和乘法都会造成溢出问题。
对于相同索引的数组交换添加条件判断,如下:
function swap(nums, a, b) {
if(a === b) return;
nums[a] ^= nums[b];
nums[b] ^= nums[a];
nums[a] ^= nums[b];
}