天天看点

不创建临时变量交换数组元素

首先讲讲交换数组的常规写法:

创建临时变量交换数组元素

function swap(nums, a,) {
  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,) {
  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,) {
  nums[a] = nums[a] + nums[b];
  nums[b] = nums[a] - nums[b];
  nums[a] = nums[a] - nums[b];
}      

优势:不用临时变量直接交换了数组两个元素

劣势:交换相同变量得到的结果为 0;两数相加可能数值溢出;

乘法运算符

function swap(nums, a,) {
  nums[a] = nums[a] * nums[b];
  nums[b] = nums[a] / nums[b];
  nums[a] = nums[a] / nums[b];
}      

总结

function swap(nums, a,) {
  if(a === b) return;
  
  nums[a] ^= nums[b];
  nums[b] ^= nums[a];
  nums[a] ^= nums[b];
}