898. 子数组按位或操作

我们有一个非负整数数组 A

对于每个(连续的)子数组 B = [A[i], A[i+1], ..., A[j]] ( i <= j),我们对 B 中的每个元素进行按位或操作,获得结果 A[i] | A[i+1] | ... | A[j]

返回可能结果的数量。 (多次出现的结果在最终答案中仅计算一次。)

 

示例 1:

输入:[0]
输出:1
解释:
只有一个可能的结果 0 。

示例 2:

输入:[1,1,2]
输出:3
解释:
可能的子数组为 [1],[1],[2],[1, 1],[1, 2],[1, 1, 2]。
产生的结果为 1,1,2,1,3,3 。
有三个唯一值,所以答案是 3 。

示例 3:

输入:[1,2,4]
输出:6
解释:
可能的结果是 1,2,3,4,6,以及 7 。

提示:

  1. 1 <= A.length <= 50000
  2. 0 <= A[i] <= 10^9

本解答借鉴了https://blog.csdn.net/qq_20633793/article/details/82314599 这篇文章,若答主介意则给删除。

本文在对原文进行了部分补充:

解答思路如下:

class Solution {
public:
    int subarrayBitwiseORs(vector<int>& A) {
        //方法1,时间复杂度为O(n^2)
        // int num=A.size();
        // unordered_set<long> ans;
        // for(int i=0;i<num;i++){
        //     long res=0;
        //     for(int j=1;j<=num-i;j++){
        //         res=A[i+j-1]|res;
        //         ans.insert(res);
        //     }
        // }
        // return ans.size();
        
        //本题关键为去重,并选用Set的数据结构用来查找,去重
        
        //假设输入为[1,4,2,8,16]
        //这里的cur2 ,是动态规划的体现
        unordered_set<int> res, cur, cur2;
        //循环n次,
        for (int i: A) {
            cur2 = {i};
          //i=8时,cur代表的是上一轮的cur2 ,为1|4|2, 4|2, 2  ,并利用set的特性将其中的冗余元素进行了去除
            //最坏情况下,在第n圈中,循环n-1次
            for (int j: cur) cur2.insert(i|j);
            //处理后,cur2代表的是1|4|2|8, 4|2|8, 2|8, 8 并利用set的特性将其中的冗余元素进行了去除
            cur = cur2;
            
            for (int j: cur) res.insert(j);    //对新结果进行了插入
        }
        return res.size();
    }
};

如下图:

方法1采用,先排除当前位,如对于2,则从A到Z方向,每一个数都利用了上一"横"层的结果,在 纵向上体现了动态规划的思想,但这里无法进行优化,只能有多少行,就内层就循环多少次,而从8到0,这里也可以采用动态规划的思想,对于每个数,都可以利用上一"竖"列的结果,而这一竖列,每一格代表其本身及其右侧进行或运算累计结果,这一数列存在大量冗余的数据,采用Set的数据结构,去除了冗余,大大地降低了时间复杂度。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值