问题描述
小R有一个长度为 n 的数组 a,她定义每个子区间 [l, r] 的权值为 a[l] | a[l+1] | ... | a[r],即该区间内所有元素的按位或运算结果。小R非常好奇,在这 n × (n + 1) / 2 个子区间中,究竟有多少种不同的权值。
她希望你能帮她计算一下,所有子区间中的不同权值总共有多少种。
测试样例
样例1:
输入:
a = [1, 2, 4]
输出:6
样例2:
输入:
a = [5, 3, 8, 1]
输出:8
样例3:
输入:
a = [1, 1]
输出:1
样例4:
输入:
a = [7, 8, 9, 10, 11]
输出:6
关键点:
- 按位或运算:按位或运算(
|)是逐位进行的,只要有一个位为1,结果的对应位就为1。 - 子区间生成:对于长度为
n的数组,子区间的数量是n * (n + 1) / 2。 - 去重:使用集合(
set)来存储不同的权值,因为集合会自动去重。
解题思路
- 理解按位或运算:按位或运算(
|)是逐位进行的,只要有一个位为1,结果的对应位就为1。 - 子区间的生成:对于长度为
n的数组,子区间的数量是n * (n + 1) / 2。 - 计算每个子区间的权值:需要计算每个子区间的按位或运算结果。
- 去重:使用集合(
set)来存储不同的权值,因为集合会自动去重。
代码分析
- 使用集合来存储不同的权值
unique_values = set()
- 遍历所有可能的子区间
for l in range(len(a)):
# 初始化当前区间的按位或结果
current_or = 0
for r in range(l, len(a)):
# 更新当前区间的按位或结果
current_or |= a[r]
# 将结果添加到集合中
unique_values.add(current_or)
- 返回集合的大小,即不同权值的数量
return len(unique_values)
完整代码演示
def solution(a):
unique_values = set()
for l in range(len(a)):
current_or = 0
for r in range(l, len(a)):
current_or |= a[r]
unique_values.add(current_or)
return len(unique_values)
关键步骤解释
- 初始化集合:
unique_values = set()用于存储不同的权值。 - 两层循环:外层循环遍历区间的起始位置
l,内层循环遍历区间的结束位置r。 - 按位或运算:
current_or |= a[r]更新当前区间的按位或结果。 - 添加到集合:
unique_values.add(current_or)将结果添加到集合中。 - 返回结果:
return len(unique_values)返回集合的大小,即不同权值的数量。
总结
通过遍历所有子区间并计算按位或结果,我们可以使用集合来去重并统计不同权值的数量。这个方法的时间复杂度为 O(n^2),适用于大多数情况。