如何重排数组使相邻元素满足兼容规则,及相关可行性判定方法咨询
问题解答
问题3:问题归类与图建模的合理性
- 该问题不属于常规排序问题范畴:常规排序依赖可传递的全序比较关系,你的需求只有局部相邻约束,没有全局大小/优先级规则,本质是带节点重复访问限制的无向图哈密顿路径构造问题
- 图节点处理远优于数组操作:
- 首先将每个id建模为无向图节点,仅当id A在id B的
canMatchWith列表、且id B也在id A的canMatchWith列表时,在A、B之间添加无向边(满足双向相邻的要求) - 问题转化为:在上述图中寻找一条路径,路径上各id的出现次数与输入数组的id出现次数完全一致
- 首先将每个id建模为无向图节点,仅当id A在id B的
问题2:可行解快速判定方法
在构造路径前可通过四步快速筛除无解情况,时间复杂度仅为O(n + m)(n为输入数组长度,m为规则总条数):
- 边界检查:若输入数组长度为1,直接判定为有解
- 基础兼容检查:对任意出现在输入中的id,过滤掉输入未出现的id后,兼容列表为空,直接判定无解
- 连通性检查:提取输入中所有出现过的id对应的子图,若该子图不连通,直接判定无解
- 频次约束检查:
- 对任意id x,若x的
canMatchWith列表不含自身(不允许自相邻),则x的出现次数不能超过ceil(输入长度/2),否则无解 - 对任意id x,若x不允许自相邻,且输入中所有与x兼容的id的总出现次数之和 < x的出现次数 - 1,直接判定无解
- 对任意id x,若x的
问题1:高效排列算法思路
因为每个节点的兼容数最多为4(度数极低),不需要使用复杂的通用路径算法,用启发式回溯+Warnsdorff规则即可达到接近线性的执行效率,远高于你当前的随机重试思路:
- 预处理:先统计输入数组中各id的剩余可使用次数,优先选择出现频次最高的id作为路径起点(减少后续分支数)
- 每一步选择下一个节点时,遵循Warnsdorff规则:从当前节点的兼容且剩余次数>0的邻居中,优先选择「后续可选邻居数量最少」的节点作为下一个元素
- 每选一个节点就将对应剩余次数减1,用完的节点直接从可选邻居列表中移除
- 仅当走到死胡同时才回溯,低度数场景下几乎不会触发回溯,执行效率极高
内容的提问来源于stack exchange,提问作者Meknassih
相关产品推荐
相关产品推荐

