【Leetcode每日一题】 综合练习 - 找出所有子集的异或总和再求和(难度⭐)(68)

1. 题目解析

题目链接:1863. 找出所有子集的异或总和再求和

这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。

2.算法原理

算法思路与实现

为了求解给定整数数组的所有子集并将其异或和相加,我们可以采用递归的方式遍历所有可能的子集。由于每个元素都有两种选择------要么在子集中,要么不在,因此我们可以通过递归函数来模拟这个过程。

递归函数设计

我们定义一个递归函数dfs,该函数接受两个参数:当前正在处理的元素下标idx和待处理的整数数组nums。函数的作用是遍历所有可能的子集选择,并计算这些子集的异或和。

返回值

该函数没有直接的返回值,因为它通过修改全局变量(如一个累加器)来累计异或和。

函数作用

函数的主要作用是:

  1. 在每个递归层级,决定当前元素nums[idx]是否应包含在当前的子集状态中。
  2. 如果包含,更新当前子集的异或和(与nums[idx]进行异或运算)。
  3. 递归调用自身,处理下一个元素(idx+1)。
  4. 如果不包含,保持当前子集的异或和不变,并递归调用自身处理下一个元素。

递归流程

  1. 递归结束条件 :当idx等于数组nums的长度时,说明已经处理完所有元素,此时将当前子集的异或和累加到总和中,并结束递归。

  2. 包含当前元素 :在当前子集的异或和基础上,与nums[idx]进行异或运算,然后递归调用dfs(idx+1, nums)处理下一个元素。

  3. 不包含当前元素 :直接递归调用dfs(idx+1, nums)处理下一个元素,当前子集的异或和保持不变。

算法步骤

  1. 初始化一个变量来累计所有子集的异或和总和。
  2. 调用递归函数dfs(0, nums),从数组的第一个元素开始处理。
  3. 在递归函数中,根据递归结束条件、包含当前元素和不包含当前元素三种情况,分别处理并更新当前子集的异或和,以及递归调用自身。
  4. 递归结束后,返回累计的异或和总和作为结果。

注意

  • 由于异或操作满足交换律和结合律,因此不需要担心子集元素的顺序。
  • 为了避免重复计算,我们使用递归而不是迭代,因为递归能够清晰地表示出所有可能的子集选择。
  • 在递归过程中,通过更新全局变量或传递引用参数来累计异或和总和。

3.代码编写

cpp 复制代码
class Solution 
{
    int sum = 0;
    int path = 0;
public:
    int subsetXORSum(vector<int>& nums) 
    {
        dfs(nums, 0);
        return sum;
    }
    void dfs(vector<int> nums, int pos)
    {
        sum += path;
        for(int i = pos; i < nums.size(); i++)
        {
            path ^= nums[i];
            dfs(nums, i + 1);
            path ^= nums[i];
        }
    }
};

The Last

嗯,就是这样啦,文章到这里就结束啦,真心感谢你花时间来读。

觉得有点收获的话,不妨给我点个吧!

如果发现文章有啥漏洞或错误的地方,欢迎私信我或者在评论里提醒一声~

相关推荐
秋难降几秒前
贪心算法:看似精明的 “短视选手”,用好了也能逆袭!💥
java·算法
xtmatao7 分钟前
WIN11+VSCODE搭建c/c++开发环境
c语言·c++·vscode
没故事的燕同学8 分钟前
C++递推
算法
一只自律的鸡11 分钟前
STL之vector
开发语言·c++·算法
岁忧30 分钟前
LeetCode 高频 SQL 50 题(基础版)之 【聚合函数】部分
数据库·sql·leetcode
梁下轻语的秋缘32 分钟前
每日c/c++题 备战蓝桥杯(P2240 【深基12.例1】部分背包问题)
c语言·c++·蓝桥杯
GEEK零零七1 小时前
Leetcode 159. 至多包含两个不同字符的最长子串
算法·leetcode·滑动窗口
zh_xuan1 小时前
c++ typeid运算符
开发语言·c++
四季如春1 小时前
C++基础 - 001 - 语言基础
c++
MindTechBuilder1 小时前
实时通信的深度技术剖析
算法