0
点赞
收藏
分享

微信扫一扫

算法题每日一练---第53天:所有子集的异或总和

一、问题描述

一个数组的 异或总和 定义为数组中所有元素按位 XOR 的结果;如果数组为  ,则异或总和为 0 。

  • 例如,数组 [2,5,6] 的 异或总和 为 2 XOR 5 XOR 6 = 1 。

给你一个数组 nums ,请你求出 nums 中每个 子集 的 异或总和 ,计算并返回这些值相加之  。

题目链接:所有子集的异或总和。

二、题目要求

样例

输入: nums = [5,1,6]
输出: 28
解释: [5,1,6] 共有 8 个子集:
- 空子集的异或总和是 0 。
- [5] 的异或总和为 5 。
- [1] 的异或总和为 1 。
- [6] 的异或总和为 6 。
- [5,1] 的异或总和为 5 XOR 1 = 4 。
- [5,6] 的异或总和为 5 XOR 6 = 3 。
- [1,6] 的异或总和为 1 XOR 6 = 7 。
- [5,1,6] 的异或总和为 5 XOR 1 XOR 6 = 2 。
0 + 5 + 1 + 6 + 4 + 3 + 7 + 2 = 28

考察

1.位运算、子集问题
2.建议用时20~40min

三、问题分析

本题是位运算的第8题,没了解过位运算相关知识点可以看这一篇文章,讲解比较详细:

算法题每日一练---第45天:位运算。

想要完成这道题目,需要攻壳两个难点:

1.子集

依靠普通的方法遍历所有的子集肯定是不行的,之前我写个一篇利用位运算实现子集的,也算是为这一题做一个铺垫吧。

算法题每日一练---第52天:位运算求解子集

2.异或计算

子集求解之后,在循环内部进行异或运算就行了,运算规则如下:

符号:^

运算规则:两个二进制位相反为1,相同为0

示例:1001^0111=1110

四、编码实现

```c++
class Solution {
public:
int subsetXORSum(vector<int>& nums) {
int i,j,n=nums.size(),sum=0,ans;//初始化变量
for(i=0;i<(1<<n);i++)//第一层for循环
{
ans=0;//初始化
for(j=0;j<n;j++)//第二层for循环
{
if(i&(1<<j))//符合条件
{
ans=ans^nums[j];//异或计算
}
}
sum+=ans;//叠加
}
return sum;
}
};


## 五、测试结果

![2.png](https://s4.51cto.com/images/blog/202205/19095253_6285a2f5619f436630.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)

![1.png](https://s4.51cto.com/images/blog/202205/19095253_6285a2f579ee153671.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)
举报

相关推荐

0 条评论