当前位置:首页 > JavaScript

js实现组合

2026-02-01 08:45:56JavaScript

组合问题的基本概念

组合是指从一组元素中选出若干个元素,不考虑顺序。例如从数组 [1, 2, 3] 中选出 2 个元素,可能的组合为 [1,2], [1,3], [2,3]

递归实现组合

递归是解决组合问题的经典方法,通过逐步缩小问题规模并合并结果:

js实现组合

function combinations(arr, k) {
  if (k === 0) return [[]];
  if (arr.length === 0) return [];

  const first = arr[0];
  const rest = arr.slice(1);

  const withFirst = combinations(rest, k - 1).map(comb => [first, ...comb]);
  const withoutFirst = combinations(rest, k);

  return [...withFirst, ...withoutFirst];
}

// 示例用法
console.log(combinations([1, 2, 3], 2)); 
// 输出: [[1, 2], [1, 3], [2, 3]]

迭代实现组合

使用位运算可以迭代生成所有可能的组合:

function combinationsIterative(arr, k) {
  const result = [];
  const n = arr.length;

  for (let mask = 0; mask < (1 << n); mask++) {
    if (countSetBits(mask) !== k) continue;

    const current = [];
    for (let i = 0; i < n; i++) {
      if (mask & (1 << i)) current.push(arr[i]);
    }
    result.push(current);
  }

  return result;
}

function countSetBits(num) {
  let count = 0;
  while (num) {
    count += num & 1;
    num >>= 1;
  }
  return count;
}

// 示例用法
console.log(combinationsIterative([1, 2, 3], 2));
// 输出: [[1, 2], [1, 3], [2, 3]]

使用生成器实现组合

ES6 生成器可以惰性地生成组合,节省内存:

js实现组合

function* combinationsGenerator(arr, k, start = 0, current = []) {
  if (current.length === k) {
    yield [...current];
    return;
  }

  for (let i = start; i < arr.length; i++) {
    current.push(arr[i]);
    yield* combinationsGenerator(arr, k, i + 1, current);
    current.pop();
  }
}

// 示例用法
const gen = combinationsGenerator([1, 2, 3], 2);
console.log([...gen]); 
// 输出: [[1, 2], [1, 3], [2, 3]]

处理大型数据集的优化

对于大型数据集,可以采用剪枝策略优化递归:

function optimizedCombinations(arr, k) {
  const result = [];

  function backtrack(start, path) {
    if (path.length === k) {
      result.push([...path]);
      return;
    }

    const maxRemaining = arr.length - (k - path.length) + 1;
    for (let i = start; i < maxRemaining; i++) {
      path.push(arr[i]);
      backtrack(i + 1, path);
      path.pop();
    }
  }

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

实际应用示例

从颜色列表中生成所有可能的双色组合:

const colors = ['red', 'green', 'blue', 'yellow'];
const colorPairs = combinations(colors, 2);

console.log(colorPairs);
// 输出: [['red', 'green'], ['red', 'blue'], ..., ['blue', 'yellow']]

这些方法覆盖了从基础到进阶的组合生成需求,可以根据具体场景选择最适合的实现方式。递归方法直观但可能堆栈溢出,迭代方法适合确定性问题,生成器适合流式处理大数据集。

标签: 组合js
分享给朋友:

相关文章

js实现日历

js实现日历

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

js 实现vue

js 实现vue

Vue.js 的基本实现 在 JavaScript 中实现 Vue.js 的核心功能,可以通过数据绑定、响应式系统和虚拟 DOM 来实现。以下是实现 Vue.js 核心功能的简化版本。 数据响应式系…

js实现变形

js实现变形

使用 CSS 和 JavaScript 实现元素变形 在 JavaScript 中实现变形效果通常结合 CSS 的 transform 属性,通过动态修改该属性实现元素的旋转、缩放、倾斜或平移。 基…

js类实现

js类实现

使用类实现 JavaScript 功能 在 JavaScript 中,类(Class)是一种语法糖,基于原型继承机制。通过 class 关键字可以更直观地定义对象模板。 基本类定义 class…

vue实现js休眠

vue实现js休眠

实现 JavaScript 休眠的方法 在 Vue 中实现 JavaScript 休眠(延迟执行)可以通过以下方式实现。由于 JavaScript 本身没有内置的 sleep 函数,通常使用 Prom…

js进度条实现

js进度条实现

使用HTML和CSS创建基础结构 在HTML中创建一个容器元素用于显示进度条,通常使用<div>元素。CSS用于设置进度条的样式,包括宽度、高度、颜色和圆角等属性。 <div cl…