当前位置:首页 > JavaScript

js数组实现全排列

2026-03-01 19:50:32JavaScript

全排列的概念

全排列是指从给定数组中取出所有元素进行排列组合,生成所有可能的顺序。对于长度为n的数组,全排列共有n!种可能。

递归实现方法

递归是解决全排列问题的经典方法。通过固定一个元素,递归生成剩余元素的全排列,再将固定的元素与递归结果拼接。

function permute(nums) {
  const result = [];

  function backtrack(current, remaining) {
    if (remaining.length === 0) {
      result.push([...current]);
      return;
    }

    for (let i = 0; i < remaining.length; i++) {
      current.push(remaining[i]);
      const newRemaining = remaining.slice(0, i).concat(remaining.slice(i + 1));
      backtrack(current, newRemaining);
      current.pop();
    }
  }

  backtrack([], nums);
  return result;
}

// 示例用法
console.log(permute([1, 2, 3]));

交换法实现

通过交换数组元素的位置来生成排列,减少内存消耗。

js数组实现全排列

function permuteSwap(nums) {
  const result = [];

  function swap(arr, i, j) {
    [arr[i], arr[j]] = [arr[j], arr[i]];
  }

  function generate(start) {
    if (start === nums.length - 1) {
      result.push([...nums]);
      return;
    }

    for (let i = start; i < nums.length; i++) {
      swap(nums, start, i);
      generate(start + 1);
      swap(nums, start, i);
    }
  }

  generate(0);
  return result;
}

使用堆算法

堆算法是一种非递归的全排列生成方法,效率较高。

function heapPermute(nums) {
  const result = [];
  const n = nums.length;
  const c = new Array(n).fill(0);

  result.push([...nums]);

  let i = 0;
  while (i < n) {
    if (c[i] < i) {
      if (i % 2 === 0) {
        [nums[0], nums[i]] = [nums[i], nums[0]];
      } else {
        [nums[c[i]], nums[i]] = [nums[i], nums[c[i]]];
      }
      result.push([...nums]);
      c[i]++;
      i = 0;
    } else {
      c[i] = 0;
      i++;
    }
  }

  return result;
}

使用库函数

现代JavaScript引擎提供了更简洁的实现方式。

js数组实现全排列

// 使用生成器函数
function* permuteGenerator(arr) {
  if (arr.length === 1) yield arr;

  for (let i = 0; i < arr.length; i++) {
    const rest = [...arr.slice(0, i), ...arr.slice(i + 1)];
    for (const p of permuteGenerator(rest)) {
      yield [arr[i], ...p];
    }
  }
}

// 转换为数组
const permutations = [...permuteGenerator([1, 2, 3])];
console.log(permutations);

性能考虑

对于大型数组,递归方法可能会导致堆栈溢出。非递归方法如堆算法更适合处理大量数据。在实际应用中,应根据数据规模选择合适的方法。

去重处理

当数组包含重复元素时,需要额外处理以避免生成重复排列。

function permuteUnique(nums) {
  const result = [];
  nums.sort((a, b) => a - b);

  function backtrack(current, remaining) {
    if (remaining.length === 0) {
      result.push([...current]);
      return;
    }

    for (let i = 0; i < remaining.length; i++) {
      if (i > 0 && remaining[i] === remaining[i - 1]) continue;
      current.push(remaining[i]);
      const newRemaining = remaining.slice(0, i).concat(remaining.slice(i + 1));
      backtrack(current, newRemaining);
      current.pop();
    }
  }

  backtrack([], nums);
  return result;
}

标签: 数组排列
分享给朋友:

相关文章

java如何输出数组

java如何输出数组

输出数组的方法 在Java中,输出数组内容有多种方式,具体取决于数组类型和输出格式需求。以下是几种常见的方法: 使用Arrays.toString()方法 适用于一维数组,直接调用Arrays.to…

vue实现数组倒叙

vue实现数组倒叙

实现数组倒序的方法 在Vue中实现数组倒序可以通过多种方式完成,以下是几种常见的方法: 使用JavaScript的reverse()方法 // 在data中定义数组 data() { retu…

vue实现数组双向绑定

vue实现数组双向绑定

实现数组双向绑定的方法 在Vue中,实现数组的双向绑定通常需要结合v-model指令或自定义事件处理。以下是几种常见的方法: 使用v-model绑定数组 Vue的v-model指令默认支持表单元素的…

react 如何修改大数组

react 如何修改大数组

修改大数组的高效方法 在React中处理大数组时,直接修改原数组可能导致性能问题。以下是几种高效处理大数组的方法: 使用不可变更新 通过创建新数组而非直接修改原数组,可以避免不必要的渲染。例如使用扩…

php数组的内部实现

php数组的内部实现

PHP数组的内部实现 PHP的数组实际上是一个有序的哈希表(Hash Table),它结合了链表和哈希表的特性,既能通过数字索引快速访问,也能通过字符串键高效查找。 哈希表结构 PHP数组的核心是z…

js实现筛选数组

js实现筛选数组

筛选数组的方法 在JavaScript中,筛选数组可以通过多种方式实现,以下是一些常见的方法: 使用Array.prototype.filter()方法filter()方法创建一个新数组,包含通过测…