有一组等间隔的范围:
range_group = [ (0,10), (10, 20), (20, 30), (30, 40), (40, 50), (50, 60), (60, 70), (70, 80), (80, 90), (90, 100)]
这些范围都是左闭右开区间,例如 (7,8)
表示 7<=x<8
。
现在有一个实数n,如何快速判断它在哪个范围内?
显然,可能有同学会这样写:
range_group = [ (0,10), (10, 20), (20, 30), (30, 40), (40, 50), (50, 60), (60, 70), (70, 80), (80, 90), (90, 100)] for pair in range_group: if pair[0] <= n < pair[1]: print(f'{n}在范围:{pair}中。')
这种方式只需要遍历range_group一遍就可以了,看起来速度还可以,时间复杂度为 O(n)
。
那么如果我有m个实数需要判断怎么办呢?此时时间复杂度将会变成 O(m*n)
。
那我们有没有更优化的办法呢?
假设 n=73
,如何让程序知道它在 [7,8)
这个范围中?
考虑到 73// 10 = 7
,而 70// 10 = 7
。其中 //
在Python 3中表示相除对结果向下取整。
于是我们可以首先构造一个字典:
range_group = [ (0,10), (10, 20), (20, 30), (30, 40), (40, 50), (50, 60), (60, 70), (70, 80), (80, 90), (90, 100)] range_dict = {x[0] // 10: x for x in range_group}
生成的 range_dict
如下图所示:
接下来,只需要从字典中找 n// 10
即可。如果找不到,那么n就是小于0或者大于等于100。
于是完整代码可以写为:
range_group = [ (0,10), (10, 20), (20, 30), (30, 40), (40, 50), (50, 60), (60, 70), (70, 80), (80, 90), (90, 100)] range_dict = {x[0] // 10: x for x in range_group} target_list = [-3, 86, 92, 104] for target in target_list: if target < 0: print('数字小于0') continue position = range_dict.get(target // 10, '大于100)') print(f'被查询的数字: {target},所在的范围为:{position}')
运行效果如下图所示:
使用这种方式,时间复杂度为 O(m)
,比直接遍历快了不少。
请大家思考,如果数字范围的间隔不是整10,应该怎么办。