209 小R的子数组权值
题解
题目描述
小 R 有一个长度为 n
的数组 a
,她定义每个子区间 [l, r]
的权值为 a[l] | a[l+1] | ... | a[r]
,即该区间内所有元素的按位或运算结果。小 R 非常好奇,在这 n × (n + 1) / 2
个子区间中,究竟有多少种不同的权值。
解题思路
对于两个二进制数 a
和 b
,如果满足 a & b = a
,从集合的角度来看,a
对应的集合是 b
对应集合的子集。
遍历数组:仍然从左到右遍历数组
a
,对于当前元素x = a[i]
。反向遍历更新:从索引
i-1
开始,向前遍历a[j]
:检查子集关系:
如果
a[j] & x != a[j]
,说明a[j]
可以通过与x
进行按位与运算而变小(即集合元素减少)。此时,更新a[j] = a[j] & x
,并将更新后的值加入结果集合res
中。如果
a[j] & x == a[j]
,则x
是a[j]
的超集。同时,由于之前的遍历已经保证了每个集合都是其左侧相邻集合的超集,x
也必然是所有左侧集合的超集。在这种情况下,进一步的遍历将不会导致任何集合的变化,因此可以直接退出内层循环,提高算法效率。
代码实现
1 |
|
复杂度分析
- 时间复杂度:
O(nlog(U))
,其中n
是数组的长度。U
是数组中的最大值 - 空间复杂度:
O(n)
,用于存储不同的权值。
参考文献
209 小R的子数组权值
https://kongshuilinhua.github.io/2024/12/24/209小R的子数组权值/