数字列表中的变位词对查找方案及编码算法咨询
解决数字变位词的编码方案
嘿,这个问题我之前处理过类似的,给你几个实用的编码思路,保证能让变位词拥有唯一且相同的编码,轻松找到列表里的变位词对:
1. 字符排序编码(最直观易实现)
这是最简单的方案:把数字转换成字符串,对字符串的字符进行排序,排序后的字符串就是它的唯一编码——因为变位词的字符组成完全相同,排序后结果必然一致。
比如:
- 12 → 转字符串"12" → 排序后"12";21 → 转字符串"21" → 排序后"12",编码完全一致
- 121排序后是"112",112排序后也是"112",完美匹配变位词特征
Python代码示例:
def generate_sort_code(num): # 把数字转字符串,排序字符后拼接成新字符串作为编码 return ''.join(sorted(str(num))) # 使用示例:用字典分组变位词 num_list = [12, 21, 121, 112, 34, 43] anagram_groups = {} for num in num_list: code = generate_sort_code(num) if code not in anagram_groups: anagram_groups[code] = [] anagram_groups[code].append(num) # 输出变位词对 for group in anagram_groups.values(): if len(group) >= 2: print(f"变位词对: {group}")
优缺点:
- 优点:实现简单,可读性强,几乎不会有溢出问题(即使是超长数字,字符串处理也能hold住)
- 缺点:排序的时间复杂度是O(k log k),k是数字的位数,对于超大规模的长数字列表,效率略低于频率统计法。
2. 数字频率统计编码(更高效的方案)
核心思路是统计数字中0-9每个数字出现的次数,把这个频率组成一个固定长度的元组(或字符串)作为编码。变位词的数字频率分布完全一致,所以编码必然相同。
比如:
- 121的数字频率是:0出现0次,1出现2次,2出现1次,3-9都是0次 → 编码元组是
(0,2,1,0,0,0,0,0,0,0) - 112的频率统计结果和上面完全一样,编码相同
Python代码示例:
def generate_freq_code(num): num_str = str(num) # 初始化0-9的频率为0 freq = [0] * 10 for c in num_str: digit = int(c) freq[digit] += 1 # 把频率列表转成元组(可哈希,能作为字典键) return tuple(freq) # 使用示例和上面类似 num_list = [12, 21, 121, 112, 34, 43] anagram_groups = {} for num in num_list: code = generate_freq_code(num) if code not in anagram_groups: anagram_groups[code] = [] anagram_groups[code].append(num) for group in anagram_groups.values(): if len(group) >= 2: print(f"变位词对: {group}")
优缺点:
- 优点:时间复杂度是O(k),比排序法更高效,适合处理大规模长数字列表
- 缺点:编码的可读性不如排序后的字符串,但作为字典键完全没问题。
3. 质数乘积编码(数学派方案)
给0-9每个数字分配一个唯一的质数,然后将数字的每个字符对应的质数相乘,乘积就是编码。因为乘法满足交换律,变位词的质数乘积必然相同;又因为质数的唯一性,不同字符组成的数字乘积不可能相同(算术基本定理)。
比如给数字分配质数:0→2,1→3,2→5,3→7,4→11,5→13,6→17,7→19,8→23,9→29
- 12的乘积是35=15,21的乘积是53=15,编码相同;
- 121的乘积是353=45,112的乘积是335=45,编码相同。
Python代码示例:
# 给0-9分配唯一质数 PRIMES = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] def generate_prime_code(num): product = 1 for c in str(num): digit = int(c) product *= PRIMES[digit] return product # 使用示例 num_list = [12, 21, 121, 112, 34, 43] anagram_groups = {} for num in num_list: code = generate_prime_code(num) if code not in anagram_groups: anagram_groups[code] = [] anagram_groups[code].append(num) for group in anagram_groups.values(): if len(group) >= 2: print(f"变位词对: {group}")
优缺点:
- 优点:编码是数字类型,有时候处理起来更方便,数学原理严谨
- 缺点:当数字位数较多时,乘积会非常大,容易出现整数溢出(Python的int虽然支持大整数,但计算效率会下降),所以适合短数字场景。
总结
- 如果是小规模列表或者追求代码简洁:选字符排序编码
- 如果是大规模长数字列表,追求效率:选数字频率统计编码
- 如果是短数字场景,喜欢数学方案:选质数乘积编码
内容的提问来源于stack exchange,提问作者Master Chief
相关产品推荐
相关产品推荐

