Leetcode刷题详解—— 找出所有子集的异或总和再求和

news/2024/7/20 21:50:41 标签: leetcode, 深度优先, 算法

1. 题目链接:leetcode.cn/problems/sum-of-all-subset-xor-totals/">1863. 找出所有子集的异或总和再求和

2. 题目描述:

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

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

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

**注意:**在本题中,元素 相同 的不同子集应 多次 计数。

数组 a 是数组 b 的一个 子集 的前提条件是:从 b 删除几个(也可能不删除)元素能够得到 a

示例 1:

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

示例 2:

输入: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

示例 3:

输入:nums = [3,4,5,6,7,8]
输出:480
解释:每个子集的全部异或总和值之和为 480 。

提示:

  • 1 <= nums.length <= 12
  • 1 <= nums[i] <= 20

3. 解法(递归)

算法思路:

所有子集可以解释为:每个元素选择在或不在一个集合中(因此,子集有2^n个)。

  1. 定义两个变量pathsum,分别表示当前子集的异或和以及所有子集的异或和之和。
  2. subsetXORSum函数中,调用dfs函数进行深度优先搜索。传入参数为输入数组nums和起始位置0
  3. dfs函数是一个递归函数,用于遍历数组的所有子集并计算它们的异或和。
  4. dfs函数中,首先将当前子集的异或和path加入总和sum中。
  5. 然后,使用一个循环从当前位置pos开始遍历数组中的每个元素。
  6. 在循环中,对当前元素进行异或操作,更新当前子集的异或和path
  7. 接着,递归调用dfs函数,传入下一个位置i + 1作为起始位置。
  8. 递归返回后,执行回溯操作,恢复当前子集的异或和path
  9. 最后,当所有子集都被遍历完毕后,返回所有子集的异或和之和sum

通过这种深度优先搜索的方式,可以遍历数组的所有子集,并计算它们的异或和之和。

请添加图片描述

C++算法代码:

class Solution {
    int path; // 当前子集的异或和
    int sum; // 所有子集的异或和之和
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]; // 回溯,恢复当前子集的异或和
        }
    }
};


http://www.niftyadmin.cn/n/5167224.html

相关文章

板刷codeforces 1000分

练习 1.Problem - 1A - Codeforces AC代码: #include <bits/stdc.h> #define endl \n #define int long long using namespace std; int n,m,a; void solve() {cin>>n>>m>>a;cout<<(n/a(n%a!0))*(m/a(m%a!0))<<endl; } signed main() {…

本地部署企业邮箱,让企业办公更安全高效

随着信息化时代的到来&#xff0c;企业邮箱几乎成了企业办公的标配&#xff0c;承载着企业业务往来和办公协同的重要职能。基于安全性、个性化需求、系统集成等方面的需要&#xff0c;许多企业选择本地部署企业邮箱&#xff0c;本地化部署不仅能有效保障企业信息安全的同时&…

Mathematica清除全局变量以及避免与内置命令冲突

自己在使用MMA的时候之前遇到过一个问题&#xff0c;就是发现使用 ClearAll["Global*"]这个命令并不能清除某些变量&#xff0c;例如 如果想要清除K这个变量则需要单独清除 Clear[K]。 实际上这是由于和MMA内部的一些预定义的命令或函数冲突的结果。其实其他变量都…

Glide加载图片占位图问题,CustomViewTarget加载图片占位图问题

Glide加载图片时通常会设置占位图。 1.Glide加载图片到imageview设置占位图 val options RequestOptions().placeholder(R.drawable.tlive_main_img_poster_default)//图片加载出来前&#xff0c;显示的图片.fallback( R.drawable.tlive_main_img_poster_default) //url为空的…

CSS3实现动态旋转加载样式

要使用 CSS3 创建一个动态旋转加载样式&#xff0c;可以使用 CSS 动画和旋转变换。下面是一个简单的示例&#xff1a; HTML&#xff1a; <div class"loader"></div> CSS&#xff1a; .loader {width: 50px;height: 50px;border: 4px solid #3498db;b…

MyBatis-Plus--在xml中使用wrapper的方法

原文网址&#xff1a;MyBatis-Plus--在xml中使用wrapper的方法_IT利刃出鞘的博客-CSDN博客 简介 本文介绍MyBatis-Plus如何在xml中使用wrapper。 Service QueryWrapper<T> wrapper new QueryWrapper<T>(); wrapper.eq("r.room_id", vo.getRoomId())…

到蒙古包了,这边天气-9度 很冷

【点我-这里送书】 本人详解 作者&#xff1a;王文峰&#xff0c;参加过 CSDN 2020年度博客之星&#xff0c;《Java王大师王天师》 公众号&#xff1a;JAVA开发王大师&#xff0c;专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生&#xff0c;期待你的…

十八章总结

一.Swing概述 二.Swing常用窗体 1.JFrame窗体 创建一个不可见、具有标题的窗体&#xff0c;关键代码&#xff1a; JFrame jfnew JFrame("登陆系统"); Container containerjf.getContentPane(); 删除容器中的按钮&#xff0c;关键代码&#xff1a; container.remo…