Ruby中shuffle哈希数组使相邻元素letter值不同的最简实现
最简实现方案
针对题目给出的专属约束(共5类letter,每类元素数量严格等于数组总长度的20%,没有任意一类的元素占比超过数组总长度的1/2),完全不需要复杂的通用重排算法、相邻校验、失败重试,从逻辑上就能100%规避相邻元素letter相同的问题。
核心设计思路
把同组元素固定间隔4个位置放置,从根源上杜绝相邻同组的可能:
- 先把原数组按照letter属性分组,拿到每个letter对应的独立元素池
- 对每个元素池内部执行随机打乱,保证同组元素的顺序随机
- 把每个组的元素,依次填充到结果数组中步长为5的位置序列上(比如某组分到起始位置0,就依次占据0、5、10...的位置;另一组分到起始位置1,就依次占据1、6、11...的位置)
- 对5个组的起始位置分配做随机打乱,进一步提升整体序列的随机程度
可直接运行的最简Ruby代码
def smart_shuffle(arr) group_count = 5 total_length = arr.length # 按letter分组 groups = arr.group_by { |item| item[:letter] }.values # 组内元素随机打乱 groups.each(&:shuffle!) # 初始化等长空结果数组 result = Array.new(total_length) # 随机打乱组顺序,让位置分配完全随机 groups.shuffle! # 逐组按步长5填充 groups.each_with_index do |group, start_pos| group.each_with_index do |item, offset| pos = start_pos + offset * group_count result[pos] = item end end result end
方案优势
- 零无效计算:同组元素的位置固定间隔4个其他组的元素,逻辑上保证不可能出现相邻同letter的情况,不需要跑完普通shuffle再逐对检查相邻元素、不符合就重新随机的循环重试
- 随机度足够:组内元素顺序随机、组的起始位置随机,最终输出的序列随机程度和原生
shuffle无实际感知差异 - 代码极简:没有多余的分支判断、回溯逻辑,完全匹配题目给出的约束条件
注意:这个方案是针对当前题目场景的专属优化,如果是通用的不等频次数组重排(比如某一类元素占比更高),需要替换为最大频次优先插入的经典重排算法。
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

