You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何查找数组关联元素并将同组值合并为多个子数组?

问题核心本质

你要实现的是无向图连通分量识别:把whoHasMe的每个下标当做独立节点,只要下标j存在于whoHasMe[i]的元素列表中,就认为节点i和j存在连通关系,所有互相连通的节点归为同一组,最终输出所有分组即可。
对于大型数组场景,用并查集(Union-Find,不交集数据结构)实现效率最高,时间复杂度接近线性,完全支持动态变化的输入数组。

实现步骤
  • 初始化并查集结构,节点总数等于whoHasMe的数组长度,每个节点初始的父节点指向自身
  • 遍历数组的每个下标i,遍历whoHasMe[i]存储的所有元素值j,将节点i和节点j执行合并操作
  • 所有节点合并完成后,遍历所有下标,按照节点的根节点值做分组,根节点相同的下标归到同一个子数组
  • 每个分组内部做升序排序,就得到最终的大数组
可直接运行的代码示例(JavaScript)
function groupConnected(whoHasMe) {
  const nodeCount = whoHasMe.length;
  // 并查集初始化
  const parent = new Array(nodeCount).fill(0).map((_, idx) => idx);
  // 查找根节点(带路径压缩)
  function find(x) {
    if (parent[x] !== x) {
      parent[x] = find(parent[x]);
    }
    return parent[x];
  }
  // 合并两个节点
  function union(x, y) {
    const rootX = find(x);
    const rootY = find(y);
    if (rootX !== rootY) {
      parent[rootY] = rootX;
    }
  }
  // 遍历所有关联关系执行合并
  for (let i = 0; i < nodeCount; i++) {
    for (const j of whoHasMe[i]) {
      union(i, j);
    }
  }
  // 按根节点分组
  const groupMap = new Map();
  for (let i = 0; i < nodeCount; i++) {
    const root = find(i);
    if (!groupMap.has(root)) {
      groupMap.set(root, []);
    }
    groupMap.get(root).push(i);
  }
  // 每个分组排序后返回
  return Array.from(groupMap.values()).map(group => group.sort((a, b) => a - b));
}

// 测试用例
const whoHasMe = [[0], [1], [0, 2, 3], [1, 2, 3, 4, 5], [4], [5], [6, 7, 8], [7], [6, 8]];
const finalBigArray = groupConnected(whoHasMe);
console.log(finalBigArray); // 输出 [[0,1,2,3,4,5], [6,7,8]],和预期结果完全一致
补充说明

这个方法是通用实现,不管whoHasMe的长度、内部元素怎么动态变化,只要关联规则不变,都能正确输出分组结果。如果数组规模极大(十万级以上节点),可以给并查集加上按秩合并的优化,性能还能进一步提升。


内容的提问来源于stack exchange,提问作者Jay Jay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 16:21:31