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

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题,没了解过位运算相关知识点可以看这一篇文章,讲解比较详细:

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

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

1.子集

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

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

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;
    }
};
复制代码

五、测试结果

2.png

1.png

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享