Python3中嵌套for循环的替代方案:学生-作业难度匹配优化
优化学生作业匹配效率的方案
首先,咱们先聊聊你当前代码的问题:嵌套循环的时间复杂度是O(n*m),当学生数量或者作业难度数据量变大时,确实会慢得离谱。而且原代码里还有个小bug——如果学生技能比所有作业难度都高,那最后一个难度对应的分数根本没加进去,因为触发了IndexError后直接break了,没处理这种边界情况。
接下来给你两个方向的解决方案:
一、高效优化方案:排序+二分查找
这是处理这类「找不超过目标值的最大元素」问题的标准高效做法,时间复杂度能降到O(m log m + n log m),数据量大的时候性能提升非常明显。
步骤逻辑:
- 把
difficulty和points配对成元组,按难度从小到大排序(默认作业难度越高分数越高,如果有特殊情况可以调整排序逻辑) - 拆分出排序后的难度列表和分数列表
- 对每个学生的技能,用二分查找快速定位到符合条件的最高难度,累加对应分数
代码示例:
import bisect def maxAssignmentPoints(self, difficulty, points, student) -> int: # 把难度和分数配对,按难度升序排序 sorted_pairs = sorted(zip(difficulty, points)) sorted_diffs = [d for d, p in sorted_pairs] sorted_points = [p for d, p in sorted_pairs] total_points = 0 for skill in student: # 找到第一个大于当前学生技能的难度索引 idx = bisect.bisect_right(sorted_diffs, skill) if idx > 0: # 取前一个索引对应的分数(即符合条件的最高难度分数) total_points += sorted_points[idx - 1] return str(total_points)
二、关于itertools.product的用法(不推荐用于大数据量)
如果你只是想尝试用itertools.product实现逻辑,那可以这么做:生成学生技能和作业难度的所有组合,对每个学生技能筛选出难度≤技能的作业,再取其中的最高分累加。但要注意,这种方法本质还是O(n*m)的时间复杂度,大数据量下依然很慢,只是写法不同而已。
代码示例:
import itertools def maxAssignmentPoints(self, difficulty, points, student) -> int: total_points = 0 # 先构建难度-分数映射,若同一难度对应多个分数,取最大值 diff_point_map = {} for d, p in zip(difficulty, points): if d not in diff_point_map or p > diff_point_map[d]: diff_point_map[d] = p for skill in student: # 生成当前学生技能与所有难度的组合,筛选出难度≤技能的项 valid_diffs = [d for s, d in itertools.product([skill], difficulty) if d <= skill] if valid_diffs: max_p = max(diff_point_map[d] for d in valid_diffs) total_points += max_p return str(total_points)
还是强烈推荐第一种排序+二分的方案,大数据量下的性能差距会非常明显。
内容的提问来源于stack exchange,提问作者StableLetterRange
相关产品推荐
相关产品推荐

