等长字符串按索引合并无序字符对去重计数的高效算法求解
高效实现方案
针对最大长度10⁶的字符串处理需求,可采用时间复杂度O(n)、空间复杂度极低的方案实现,核心思路如下:
核心逻辑
- 无序对统一编码:对于每个索引取出的两个字符
c1、c2,将「较小字符+较大字符」作为唯一标识key(比如"ba"和"ab"的key都为"ab"),避免重复判断。 - 计数与结果分离:用独立的计数结构记录每个无序对的出现次数,同时维护结果数组的插入顺序。
优化实现要点
- 优先用数组代替哈希表做计数:如果明确字符范围(比如仅小写字母、ASCII字符),可将字符对编码为整数作为数组下标,完全避免哈希冲突开销。比如小写字母的无序对最多只有
26*27/2=351种,仅需长度为351的数组即可完成计数,访问速度远高于哈希表。 - 仅在首次出现时写入结果数组:遍历过程中判断当前字符对的计数是否从0变为1,是则将首次出现的原始字符对加入结果数组,否则仅更新计数。
示例代码(Python)
def process_strings(s1: str, s2: str) -> tuple[list[str], list[int]]: n = min(len(s1), len(s2)) # 针对小写字母优化,可根据实际字符范围调整 max_key = 26 * 27 // 2 count = [0] * max_key added = [False] * max_key res = [] count_res = [] ord_a = ord('a') for i in range(n): c1_ord = ord(s1[i]) - ord_a c2_ord = ord(s2[i]) - ord_a # 生成统一key min_c, max_c = min(c1_ord, c2_ord), max(c1_ord, c2_ord) key = min_c * 26 + max_c count[key] += 1 # 首次出现则加入结果数组,保留原始字符顺序 if not added[key]: added[key] = True res.append(f"{s1[i]}{s2[i]}") # 生成对应计数数组(可选) for pair in res: c1_ord = ord(pair[0]) - ord_a c2_ord = ord(pair[1]) - ord_a min_c, max_c = min(c1_ord, c2_ord), max(c1_ord, c2_ord) count_res.append(count[min_c * 26 + max_c]) return res, count_res
性能说明
该方案遍历10⁶长度的字符串仅需一次循环,单步操作均为O(1)时间开销,普通消费级CPU可在10ms以内完成全部运算。即使字符范围不确定,使用哈希表存储计数的性能也完全满足需求,最多仅需存储10⁶个键值对,内存占用可控制在几十MB以内。
内容的提问来源于stack exchange,提问作者isetnt
相关产品推荐
相关产品推荐

