技术问询:基于图论判断排列A能否通过指定良好交换对转换为排列B
解决排列交换可行性问题:仅用指定位置对将排列A转换为B
嘿,这个问题本质上是图论中连通分量的典型应用,我来给你一步步拆解清楚怎么判断转换是否可行~
问题明确
先把问题再梳理一遍,确保我们理解一致:
给定两个长度为N的排列A和B,以及一组允许交换的位置对(称为"good pairs"),判断是否可以通过任意次数交换这些位置对中的元素,将排列A转换成排列B。
核心思路
每个允许的交换对,相当于在两个位置之间连了一条无向边。这样所有位置就被划分成了若干个连通分量——在同一个分量里的位置,你可以通过一系列允许的交换,把这些位置上的元素任意置换(因为连通意味着元素可以在分量内部自由移动)。
那判断的关键条件就很清晰了:
对于每个连通分量对应的位置集合,排列A在这些位置上的元素集合,必须和排列B在这些位置上的元素集合完全一致。
换句话说,你只能在连通分量内部调整元素顺序,所以内部的元素必须和目标的元素完全匹配,才能通过交换得到目标排列。
示例验证
用你给出的例子来验证这个思路:
- N=4,A=[1,3,2,4],B=[1,4,2,3],允许交换的位置对是[[2,4]]
- 位置的连通分量:{1}, {2,4}, {3}
- 分量{1}:A和B的元素都是1,匹配
- 分量{2,4}:A的元素是[3,4],B的元素是[4,3],元素集合完全相同,通过一次交换就能匹配
- 分量{3}:A和B的元素都是2,匹配
- 所有分量都满足条件,所以转换可行。
具体实现步骤
我们可以用**并查集(Union-Find/DSU)**来高效管理连通分量,步骤如下:
- 初始化并查集,每个位置作为独立节点。
- 遍历所有允许的交换对,将对应的位置合并到同一个连通分量中。
- 按连通分量分组,分别收集A和B中对应位置的元素。
- 检查每个分组的元素集合是否一致,全部一致则返回True,否则返回False。
代码实现(Python)
class DSU: def __init__(self, size): # 位置是1-based(题目示例里位置用2、4表示),所以数组从1到size self.parent = list(range(size + 1)) self.rank = [0] * (size + 1) def find(self, x): # 路径压缩,加快查询速度 if self.parent[x] != x: self.parent[x] = self.find(self.parent[x]) return self.parent[x] def union(self, x, y): # 按秩合并,保证树的高度尽可能小 x_root = self.find(x) y_root = self.find(y) if x_root == y_root: return if self.rank[x_root] < self.rank[y_root]: self.parent[x_root] = y_root else: self.parent[y_root] = x_root if self.rank[x_root] == self.rank[y_root]: self.rank[x_root] += 1 def can_transform(A, B, good_pairs, n): dsu = DSU(n) # 合并所有允许交换的位置对 for u, v in good_pairs: dsu.union(u, v) # 按连通分量分组收集元素 group_a = {} group_b = {} for pos in range(1, n + 1): root = dsu.find(pos) # 注意A和B是0-based列表,位置是1-based,所以索引要减1 val_a = A[pos - 1] val_b = B[pos - 1] if root not in group_a: group_a[root] = [] group_b[root] = [] group_a[root].append(val_a) group_b[root].append(val_b) # 检查每个分组的元素是否匹配(排序后比较,因为排列元素唯一) for root in group_a: if sorted(group_a[root]) != sorted(group_b[root]): return False return True # 测试示例 A = [1, 3, 2, 4] B = [1, 4, 2, 3] C = [[2, 4]] N = 4 print(can_transform(A, B, C, N)) # 输出: True
边界情况补充
- 如果A和B本身完全相同,不管交换对是什么,都直接返回True
- 如果交换对为空,每个位置都是独立连通分量,此时必须A和B完全一致才能转换
- 如果某个连通分量里A的元素集合和B的不匹配(比如A是[2,3],B是[2,4]),那绝对无法转换,因为没法从外部获取缺失的元素
内容的提问来源于stack exchange,提问作者Dikshant Dwivedi
相关产品推荐
相关产品推荐

