Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、问题描述
一个数组的 异或总和 定义为数组中所有元素按位 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题,没了解过位运算相关知识点可以看这一篇文章,讲解比较详细:
想要完成这道题目,需要攻壳两个难点:
1.子集
依靠普通的方法遍历所有的子集肯定是不行的,之前我写个一篇利用位运算实现子集的,也算是为这一题做一个铺垫吧。
2.异或计算
子集求解之后,在循环内部进行异或运算就行了,运算规则如下:
符号:^
运算规则:两个二进制位相反为1,相同为0
示例:1001^0111=1110
四、编码实现
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;
}
};
复制代码
五、测试结果
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END