📜  所有子数组的按位或的总和(1)

📅  最后修改于: 2023-12-03 15:09:59.559000             🧑  作者: Mango

所有子数组的按位或的总和

给定一个整数数组,找到所有长度大于等于1的子数组,将子数组中的所有数进行按位或运算,最终将所得结果进行求和,返回结果即为所有子数组的按位或的总和。

例如:输入数组[1,2,3],则所有子数组为[1],[2],[3],[1,2],[2,3],[1,2,3],按位或的结果分别为1, 2, 3, 3, 3, 3,最终求和为15。

解法

这道题有多种解法,其中一种比较好理解的解法是动态规划。对于给定的数组,定义一个dp数组,其中dp[i][j]表示从第i个元素开始到第j个元素为止的子数组中按位或的结果。则 dp[i][j] = dp[i+1][j] | nums[i],因为第i个元素一定会在以它为开头的子数组中出现,所以我们只需考虑i+1到j之间的元素按位或的结果,再把第i个元素的值进行按位或运算即可。遍历所有子数组,将结果进行累加即为最终的答案。

代码如下:

class Solution:
    def subarrayBitwiseORs(self, nums: List[int]) -> int:
        n = len(nums)
        dp = [[0] * n for _ in range(n)]
        ans = set()

        for i in range(n):
            dp[i][i] = nums[i]
            ans.add(dp[i][i])

        for i in range(n-1, -1, -1):
            for j in range(i+1, n):
                dp[i][j] = dp[i+1][j] | nums[i]
                ans.add(dp[i][j])

        return len(ans)
复杂度分析

时间复杂度:$O(n^2)$,其中n为输入数组的长度,因为我们需要遍历每个子数组,并计算其按位或的结果。

空间复杂度:$O(n^2)$,因为我们需要一个dp数组来存储已经计算的结果。