子数组按位或操作(failed)

本文探讨了如何计算一个非负整数数组的所有连续子数组的按位或运算结果,并去除重复值后的数量。通过使用无序集合进行去重和遍历子序列,实现了高效的算法解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们有一个非负整数数组 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

 

来自top榜的答案

分析 先用无序set去重,一边去重一边遍历出当前(就是个子序列,实际上就是一边去重一边遍历出子序列,

再进行或运算,一次循环出一次子序列的运算值,再放到ans里再次去重 所得的size就是答案个数

class Solution {
public:
    int subarrayBitwiseORs(vector<int>& a) {
        int n=a.size();
        unordered_set<int> u,ans;        
        for(int i=0;i<n;i++){
            unordered_set<int> v;
            v.insert(a[i]);
            for(int x:u)v.insert(a[i]|x);
            ans.insert(v.begin(),v.end());
            u=v;
        }
        return ans.size();
    }
};

 

### C语言中子函数返回字符数组的实现 在C语言中,由于函数无法直接返回数组类型的数据,因此通常通过以下几种方式来实现在子函数中返回字符数组的功能。 #### 方法一:使用结构体封装字符数组 可以通过定义一个结构体,在其中包含字符数组成员变量。这样可以将整个结构体作为函数的返回值,从而间接实现返回字符数组的目的[^1]。 ```c #include <stdio.h> #include <string.h> struct ret { char buf[100]; }; struct ret test(const char *input) { struct ret result; strncpy(result.buf, input, sizeof(result.buf) - 1); result.buf[sizeof(result.buf) - 1] = '\0'; // 确保字符串以\0结尾 return result; } void main(void) { struct ret b; b = test("用结构体作为返回值传递数组"); printf("%s\n", b.buf); } ``` 上述代码展示了如何通过结构体的方式返回字符数组,并将其打印出来。 --- #### 方法二:动态分配内存并返回指针 另一种常见的方式是在子函数内部为字符数组分配动态内存(`malloc`),并将指向该内存区域的指针作为返回值。需要注意的是,调用者有责任释放这块内存以防止内存泄漏[^4]。 ```c #include <stdio.h> #include <stdlib.h> #include <string.h> char* getCharArray(int len) { char* array = (char*)malloc(len * sizeof(char)); if (!array) { fprintf(stderr, "Memory allocation failed!\n"); exit(1); } strncpy(array, "getCharsArrayByPoint from china!", len - 1); array[len - 1] = '\0'; return array; } int main() { int length = 50; char* str = getCharArray(length); printf("Returned string: %s\n", str); free(str); // 记得释放动态分配的内存 return 0; } ``` 此方法适用于需要灵活控制数组大小的情况,但需注意资源管理问题。 --- #### 方法三:传入缓冲区地址 还可以让调用方提供一块已有的存储空间(即缓冲区),并通过参数形式传递给子函数。这种方式无需涉及复杂的内存管理操作,适合于固定长度的需求场景[^3]。 ```c #include <stdio.h> #include <string.h> void fillBuffer(char buffer[], size_t bufferSize) { const char source[] = "填充到缓冲区的内容"; strncpy(buffer, source, bufferSize - 1); buffer[bufferSize - 1] = '\0'; // 确保安全终止符 } int main() { char myBuffer[100]; // 提供足够的空间 fillBuffer(myBuffer, sizeof(myBuffer)); printf("Filled Buffer Content: %s\n", myBuffer); return 0; } ``` 这种方法简单高效,尤其当目标数据量较小时尤为适用。 --- #### 总结 以上三种方案各有优劣: - **结构体封装**易于理解且安全性较高; - **动态分配内存**灵活性强但增加了复杂度以及潜在的风险; - **传入缓冲区地址**则最为简洁明了,不过依赖外部提供的存储位置可能带来局限性。 具体选用哪种取决于实际应用场景和个人偏好。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值