如何优雅高效地查找二维数组中的重复元素配对?
优雅高效地查找二维数组中重复元素的配对方法
这个需求其实挺典型的,想要优雅又高效地实现,核心思路就是用**哈希表(关联数组)**来做值到坐标的映射,避免暴力两两对比的O((NM)²)低效复杂度,咱们可以把时间复杂度降到O(NM)——这在数组规模较大的时候差异会特别明显。
具体实现思路
- 构建值到坐标的映射:遍历整个二维数组,把每个元素的值作为键,对应的
[行索引, 列索引]坐标作为值存入哈希表。这样同一个值的所有坐标都会被集中在一起。 - 生成配对与未匹配项:遍历哈希表,对于每个值对应的坐标列表:
- 如果列表长度大于1,就生成所有不重复的两两配对(比如只生成
[A,B]而不重复生成[B,A]) - 如果列表长度为1,就把这个坐标标记为无匹配项
- 如果列表长度大于1,就生成所有不重复的两两配对(比如只生成
PHP代码实现
function findDuplicatePairs($arr) { $valueMap = []; $rows = count($arr); // 第一步:遍历数组,建立值到坐标集合的映射 for ($i = 0; $i < $rows; $i++) { $cols = count($arr[$i]); for ($j = 0; $j < $cols; $j++) { $value = $arr[$i][$j]; // 如果当前值还没在映射里,初始化空数组 if (!isset($valueMap[$value])) { $valueMap[$value] = []; } // 将当前坐标加入对应值的列表 $valueMap[$value][] = [$i, $j]; } } $duplicatePairs = []; $unmatchedCoords = []; // 第二步:处理映射结果,生成配对和未匹配项 foreach ($valueMap as $coords) { $coordCount = count($coords); if ($coordCount === 1) { // 只有一个坐标,加入未匹配列表 $unmatchedCoords[] = $coords[0]; } else { // 生成所有不重复的两两配对 for ($x = 0; $x < $coordCount; $x++) { for ($y = $x + 1; $y < $coordCount; $y++) { $duplicatePairs[] = [$coords[$x], $coords[$y]]; } } } } // 返回结构化的结果,方便使用 return [ 'duplicate_pairs' => $duplicatePairs, 'unmatched' => $unmatchedCoords ]; } // 测试你给出的示例数组 $a = [ ['a','b','c'], ['d','a','e'], ['d','c','b'] ]; $result = findDuplicatePairs($a); print_r($result);
代码运行结果
运行后会得到和你预期一致的结果:
duplicate_pairs里包含所有重复元素的配对:[[[0,0],[1,1]], [[0,1],[2,2]], [[0,2],[2,1]], [[1,0],[2,0]]]unmatched里是无匹配的坐标:[[1,2]]
为什么这个方案高效?
- 时间效率:只需要遍历数组一次(O(N*M)),后续处理映射的时间也是线性的,整体复杂度远低于暴力法。
- 空间效率:最坏情况(所有元素都不同)需要存储所有坐标,这是必要的开销,但在大多数场景下都是可接受的。
- 可读性:逻辑清晰,分成两步处理,代码注释也很明确,后期维护起来很方便。
如果需要严格按照你示例里的格式把所有结果放在一个数组里,只需要把$duplicatePairs和$unmatchedCoords合并成一个数组返回即可,调整起来很灵活。
内容的提问来源于stack exchange,提问作者FKranhold
相关产品推荐
相关产品推荐

