华为OD机试_2025 B卷_计算最大乘积(Python,100分)(附详细解题思路)
题目描述
给定一个元素类型为小写字符串的数组,请计算两个没有相同字符的元素长度乘积的最大值,
如果没有符合条件的两个元素,返回0。
输入描述
输入为一个半角逗号分隔的小写字符串的数组,2 <= 数组长度<=100,0 < 字符串长度<= 50。
输出描述
两个没有相同字符的元素 长度乘积的最大值。
用例
输入 | iwdvpbn,hk,iuop,iikd,kadgpf |
输出 | 14 |
说明 | 数组中有5个元素。 iwdvpbn与hk无相同的字符,满足条件,iwdvpbn的长度为7,hk的长度为2,乘积为14(7*2)。 iwdvpbn与iuop、iikd、kadgpf均有相同的字符,不满足条件。 iuop与iikd、kadgpf均有相同的字符,不满足条件。 iikd与kadgpf有相同的字符,不满足条件。 因此,输出为14。 |
无相同字符长度最大乘积计算
核心解题思路
题目要求找出数组中两个不含相同字符的字符串,使它们的长度乘积最大化。解题关键在于:
- 双重遍历:检查所有可能的字符串组合
- 字符交集检测:利用集合判断两个字符串是否有相同字符
- 乘积最大化:跟踪并更新最大长度乘积
关键步骤
- 预处理字符集合:
- 为每个字符串创建字符集合
- 存储字符串长度,避免重复计算
- 双重循环遍历:
- 外层循环遍历每个字符串
- 内层循环遍历后续字符串
- 交集检查:
- 使用集合交集操作
set1 & set2
- 若交集为空集,则无相同字符
- 使用集合交集操作
- 乘积计算与更新:
- 计算当前组合的长度乘积
- 更新全局最大乘积
完整代码实现
def max_length_product():# 输入处理arr = input().strip().split(',')n = len(arr)# 预处理:创建字符集合并记录长度sets = [set(s) for s in arr]lengths = [len(s) for s in arr]max_product = 0 # 存储最大乘积# 双重遍历所有字符串组合for i in range(n):for j in range(i + 1, n):# 检查是否有相同字符if not (sets[i] & sets[j]): # 交集为空product = lengths[i] * lengths[j]if product > max_product:max_product = productreturn max_product# 主程序
if __name__ == "__main__":result = max_length_product()print(result)
算法原理解析
1. 预处理优化
sets = [set(s) for s in arr] # 字符集合列表
lengths = [len(s) for s in arr] # 长度列表
- 集合转换:将字符串转为字符集合,便于高效交集检测
- 长度存储:预先计算长度避免重复调用len()
2. 双重遍历机制
for i in range(n):for j in range(i + 1, n):
- 外层索引
i
从0到n-1 - 内层索引
j
从i+1
开始,避免重复组合 - 总共检查C(n,2) = n(n-1)/2种组合
3. 交集检测优化
if not (sets[i] & sets[j]):
&
操作符计算集合交集- 交集为空时表达式为False,
not
转为True - 时间复杂度:O(min(len(set1), len(set2)))
4. 乘积比较与更新
product = lengths[i] * lengths[j]
if product > max_product:max_product = product
- 仅当无相同字符时才计算乘积
- 简单比较更新最大值,无需额外数据结构
示例解析:输入"iwdvpbn,hk,iuop,iikd,kadgpf"
字符串信息
字符串 | 长度 | 字符集合 |
---|---|---|
iwdvpbn | 7 | {i,w,d,v,p,b,n} |
hk | 2 | {h,k} |
iuop | 4 | {i,u,o,p} |
iikd | 4 | {i,k,d} |
kadgpf | 6 | {k,a,d,g,p,f} |
关键组合检测
-
iwdvpbn & hk:
- 集合交集:{i,w,d,v,p,b,n} ∩ {h,k} = ∅
- 无相同字符 → 计算乘积:7×2=14
- 更新max_product=14
-
iwdvpbn & iuop:
- 交集:{i,w,d,v,p,b,n} ∩ {i,u,o,p} = {i,p} ≠ ∅
- 跳过
-
iwdvpbn & iikd:
- 交集:{i,w,d,v,p,b,n} ∩ {i,k,d} = {i,d} ≠ ∅
- 跳过
-
iwdvpbn & kadgpf:
- 交集:{i,w,d,v,p,b,n} ∩ {k,a,d,g,p,f} = {d,p} ≠ ∅
- 跳过
-
hk & iuop:
- 交集:{h,k} ∩ {i,u,o,p} = ∅
- 乘积:2×4=8 <14 → 不更新
-
hk & iikd:
- 交集:{h,k} ∩ {i,k,d} = {k} ≠ ∅
- 跳过
-
hk & kadgpf:
- 交集:{h,k} ∩ {k,a,d,g,p,f} = {k} ≠ ∅
- 跳过
-
iuop & iikd:
- 交集:{i,u,o,p} ∩ {i,k,d} = {i} ≠ ∅
- 跳过
-
iuop & kadgpf:
- 交集:{i,u,o,p} ∩ {k,a,d,g,p,f} = {p} ≠ ∅
- 跳过
-
iikd & kadgpf:
- 交集:{i,k,d} ∩ {k,a,d,g,p,f} = {k,d} ≠ ∅
- 跳过
最终结果:14
算法优化分析
时间复杂度
- 预处理:O(n×m),n为字符串数,m为平均长度
- 双重遍历:O(n²)
- 交集检测:O(min(len(s1), len(s2)))
总体:O(n×m + n²×min(m)),题目限制n≤100,m≤50 → 高效
空间复杂度
- 集合列表:O(n×m)
- 长度列表:O(n)
总体:O(n×m),可接受范围内
优势
- 简洁明了:直接实现问题要求
- 高效检测:集合操作优化字符检查
- 避免重复:组合遍历不重复
- 边界处理:自动处理空输入等情况
边界情况测试
测试1:全相同字符
输入:“abc,abc,abc”
输出:0
解析:所有字符串都有相同字符,无有效组合
测试2:完全不相交
输入:“abc,def,ghi”
输出:max(3×3, 3×3, 3×3)=9
解析:所有组合都有效,取最长乘积
测试3:部分相交
输入:“abc,ade,xyz”
输出:3×3=9(“abc"和"xyz”)
解析:"abc"和"ade"有共同字符’a’,跳过
测试4:单字符字符串
输入:“a,b,c,d,e”
输出:1(任意两个单字符组合)
解析:所有字符都不同,乘积为1
测试5:空输入
输入:“”
输出:0
解析:数组为空,无组合
总结
算法适用场景
- 相似度计算:文档/基因序列相似度分析
- 资源分配:互斥任务分配优化
- 推荐系统:互补产品推荐
- 广告投放:用户兴趣标签互斥组合
- 密码学:密钥无冲突组合
扩展思考
- 多字符串组合:找出三个无相同字符的字符串
- 权重优化:考虑字符频率而不仅存在性
- 近似匹配:允许少量相同字符
- 大规模优化:使用位图表示字符集合(适用于有限字符集)
这种双重遍历+集合检测的方法直观高效,是解决此类问题的标准方法,可扩展到更复杂的字符串处理场景中。