当前位置:首页 > JavaScript

js实现排列

2026-03-13 18:57:30JavaScript

排列的概念

排列是指从一组元素中按照一定顺序选取若干个元素的所有可能组合。例如,从 [1, 2, 3] 中选取 2 个元素的排列为 [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]。

递归实现排列

递归是一种常见的排列生成方法,通过逐步固定前缀并递归处理剩余元素实现。

function permute(arr) {
  const result = [];
  const 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([], arr);
  return result;
}

堆算法(非递归实现)

堆算法通过交换元素位置生成排列,适合内存敏感的场景。

function heapPermute(arr) {
  const result = [];
  const generate = (n, arr) => {
    if (n === 1) {
      result.push([...arr]);
      return;
    }
    for (let i = 0; i < n; i++) {
      generate(n - 1, arr);
      if (n % 2 === 0) {
        [arr[i], arr[n - 1]] = [arr[n - 1], arr[i]];
      } else {
        [arr[0], arr[n - 1]] = [arr[n - 1], arr[0]];
      }
    }
  };
  generate(arr.length, arr);
  return result;
}

使用生成器实现排列

生成器可以按需生成排列,避免一次性占用过多内存。

function* permuteGenerator(arr) {
  if (arr.length <= 1) yield arr;
  else {
    const [first, ...rest] = arr;
    for (const perm of permuteGenerator(rest)) {
      for (let i = 0; i <= perm.length; i++) {
        yield [...perm.slice(0, i), first, ...perm.slice(i)];
      }
    }
  }
}

处理重复元素的排列

当输入数组包含重复元素时,需跳过重复排列。

js实现排列

function permuteUnique(arr) {
  const result = [];
  arr.sort((a, b) => a - b);
  const 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([], arr);
  return result;
}

性能优化建议

对于大规模数据,考虑使用迭代替代递归,或采用惰性求值(如生成器)。实际应用中可根据具体需求选择递归、堆算法或库函数实现。

标签: 排列js
分享给朋友:

相关文章

js 实现vue

js 实现vue

实现 Vue 的核心功能 在 JavaScript 中实现 Vue 的核心功能需要模拟数据绑定、虚拟 DOM 和响应式系统。以下是一个简化版的实现思路: 响应式系统 通过 Object.define…

js实现继承

js实现继承

原型链继承 通过将子类的原型指向父类的实例实现继承。子类实例可以访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Parent…

js实现日历

js实现日历

实现日历的基本思路 使用JavaScript实现日历的核心是动态生成日期表格,并处理月份切换逻辑。需要计算当前月的天数、起始星期几,并动态渲染到页面上。 获取当前日期信息 通过Date对象获取当前年…

js实现论坛

js实现论坛

实现论坛的基本功能 使用JavaScript实现一个论坛需要结合前端和后端技术。前端可以使用React、Vue或Angular等框架,后端可以选择Node.js配合Express或Koa框架。数据库可…

jquery js

jquery js

jQuery 简介 jQuery 是一个快速、简洁的 JavaScript 库,简化了 HTML 文档遍历、事件处理、动画和 Ajax 交互。它兼容多种浏览器,提供易于使用的 API,使开发者能够更高…

js实现驼峰

js实现驼峰

实现驼峰命名的几种方法 使用正则表达式和字符串替换 通过正则表达式匹配字符串中的特定模式(如下划线或短横线),并将其后的字母转换为大写,同时移除分隔符。 function toCamelCase(s…