问题描述
小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
题目分析
问题理解
- 子区间:对于一个长度为
n的数组a,子区间[l, r]表示从索引l到索引r的所有元素。 - 按位或运算:对于子区间
[l, r],其权值为a[l] | a[l+1] | ... | a[r],即该区间内所有元素的按位或运算结果。 - 不同权值的数量:我们需要统计所有可能的子区间的按位或运算结果,并找出这些结果中有多少种不同的值。
数据结构的选择
- 集合:为了存储不同的权值,我们可以使用集合(
set),因为集合会自动去重。
算法步骤
-
遍历所有子区间:
- 使用两层循环,外层循环遍历区间的起始位置
l,内层循环遍历区间的结束位置r。
- 使用两层循环,外层循环遍历区间的起始位置
-
计算当前子区间的权值:
- 对于每个子区间
[l, r],计算其按位或运算结果,并将其加入集合中。
- 对于每个子区间
-
统计不同权值的数量:
- 最终集合的大小即为不同权值的数量。
复杂度分析
- 时间复杂度:由于需要遍历所有子区间,时间复杂度为
O(n^2),其中n是数组的长度。 - 空间复杂度:使用了一个集合来存储不同的权值,空间复杂度为
O(n^2),因为最坏情况下所有子区间的权值都不同。
题解
def solution(a):
# 使用集合来存储不同的权值
unique_values = set()
# 遍历所有可能的子区间
for l in range(len(a)):
# 初始化当前区间的权值
current_value = 0
for r in range(l, len(a)):
# 计算当前区间的权值
current_value |= a[r]
# 将当前区间的权值加入集合
unique_values.add(current_value)
# 返回不同权值的数量
return len(unique_values)
if __name__ == '__main__':
print(solution([1, 2, 4]) == 6)
print(solution([5, 3, 8, 1]) == 8)
print(solution([1, 1]) == 1)
print(solution([7, 8, 9, 10, 11]) == 6)
分析
解法思路
-
使用集合存储不同的权值:
- 你使用了
set来存储不同的权值,这样可以自动去重。
- 你使用了
-
遍历所有可能的子区间:
- 你使用了两个嵌套的循环来遍历所有可能的子区间
[l, r],其中l是区间的起始位置,r是区间的结束位置。
- 你使用了两个嵌套的循环来遍历所有可能的子区间
-
计算当前子区间的权值:
- 对于每个子区间
[l, r],你通过按位或运算current_value |= a[r]来计算当前区间的权值,并将其加入集合unique_values中。
- 对于每个子区间
-
统计不同权值的数量:
- 最终,集合
unique_values的大小即为不同权值的数量。
- 最终,集合