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

news/2024/11/29 8:33:40/

​​题目来源:

        leetcode题目,网址:1863. 找出所有子集的异或总和再求和 - 力扣(LeetCode)

解题思路:

        尝试一:

                思路:暴力递归,每次将数组中的元素删去一个得到新的数组,异或后再求和。在递归过程中会产生大量重复,所以需要对当前层数计数,原始数组层数为 0,每删去一个元素层数加一,最后返回时若层数 x 大于1 ,则当前子数组计算了 x 次,需要将结果除以 x 后返回。

                注意: 计算时因为要除以 x ,所以要以递归函数返回类型为 double,因为除法过程中可能产生无限循环小数或其余情况,因此最后的和与实际和可能有细微区别,因此在强制转换时需要四舍五入取整而不是默认的向 0 取整。

                结果:第 24 个测试用例超时。

        尝试二:

                思路:在暴力递归时使用哈希表记录计算过的元素组合从而避免一些重复计算。

                结果:第 8 个测试用例 [1,1,1] 报错,前两个元素组成的 [1,1] 和后两个元素组成的 [1,1] 需要计算两次,但哈希表中是相同的,计算被跳过了。

        尝试三:

                思路:在暴力递归时使用哈希表记录计算过的位置组合从而避免重复计算。

                结果:通过,但执行用时仅击败 5.33%,内存消耗仅击败 5.34%。应该有基于数学的   O(n) 或 O(1) 解法。

解题代码:

//尝试一:
class Solution {public int subsetXORSum(int[] nums) {int total=nums[0];ArrayList<Integer> list=new ArrayList<>();list.add(nums[0]);for(int i=1;i<nums.length;i++){total=total^nums[i];list.add(nums[i]);}return (int)(assist(list,total,0)+0.5);}public double assist(ArrayList<Integer> list,int total,int depth){double res=total;for(int i=0;i<list.size();i++){ArrayList<Integer> temp=new ArrayList<>(list);int tempTotal=total^list.get(i);temp.remove(i);res+=assist(temp,tempTotal,depth+1);}return depth==0?res:res/depth;}
}
//尝试三
class Solution {Set<ArrayList<Integer>> subset=new HashSet<>();public int subsetXORSum(int[] nums) {int total=nums[0];ArrayList<Integer> list=new ArrayList<>();ArrayList<Integer> posList=new ArrayList<>();list.add(nums[0]);posList.add(0);for(int i=1;i<nums.length;i++){total=total^nums[i];list.add(nums[i]);posList.add(i);}return assist(list,total,posList);}public int assist(ArrayList<Integer> list,int total,ArrayList<Integer> posList){if(!subset.contains(posList)){subset.add(posList);}else{return 0;}int res=total;for(int i=0;i<list.size();i++){if(list.get(i)==-1){continue;}ArrayList<Integer> temp=new ArrayList<>(list);ArrayList<Integer> tempPos=new ArrayList<>(posList);int tempTotal=total^list.get(i);temp.set(i,-1);tempPos.set(i,-1);res+=assist(temp,tempTotal,tempPos);}return res;}
}

总结:

        官方题解给出了三种解法。

        第一种是递归枚举子集。从第一个元素开始,取或不取造成两个不同的分支,然后每多一个元素,分支数*2。处理完最后一个元素后,对异或结果求和即可。

        第二种是迭代法枚举子集。一个长度为 n 的数组有 2^n 个子集,将其映射到 [0,2^n-1] ,其中一个整数的第 i 位表示第 i 个元素是否被选取,这样遍历从 0 到 2^n-1 计算异或求和即可。

        第三种是按位考虑+二项式展开。是根据展开式和数学解答的。没看太懂。 



http://www.ppmy.cn/news/666625.html

相关文章

接口签名验证

1.appId和secretKey定义 appIdAPPID secretKey cfq4189auoo13y17ur9n2rl7v2tkz3iq 2.sign获取算法 md5&#xff08;secretKey参数json字符串timestampsecretKey&#xff09;后的大写字母。 /*** 参数按key进行排序* param obj* return*/public static String getParamStr(Objec…

文件和目录扫描

0x01漏洞原理&#xff1a; 程序在实现上没有充分过滤用户输入的/之类的目录跳转符&#xff0c;导致恶意用户可以通过提交目录跳转来遍历服务器上的任意文件。 0x02工具介绍 0x01御剑 在“域名框”输入你要扫描的域名&#xff0c;然后点击扫描。 根据自身电脑配置&#xff0…

计算机扫描的文件保存在哪,电脑教程:文件扫描后自动保存哪里去了

科技本身&#xff0c;支配宇宙的自然规律是充满魅力的&#xff01;因此越来越多的人开始关注科技的相关动态&#xff0c;近来文件扫描后自动保存哪里去了的消息也是引起了很多人的关注&#xff0c;那么既然现在大家都想要知道文件扫描后自动保存哪里去了&#xff0c;小编今天就…

C语言的文件扫描

/* **************************************************************************** ******文件扫描 ******使用:向address变量输入要搜索的磁盘(亦或者目录地址)即可搜索目录下所有的文件(包括多层文件夹) ******如:输入 C:\\a*. 将会搜索a文件夹里所有的文件和文件夹,当a文件…

Duplicate Cleaner - 重复文件 / 相似文件扫描

Duplicate Cleaner - 重复文件 / 相似文件扫描 https://www.duplicatecleaner.com/ Duplicate Cleaner is a tool for finding and removing duplicate files from your computer or network drives. It is intended to be used on user content - documents, photos, images,…

Android中的文件扫描

在android中我们有时会做有关电子书阅读器、音乐播放器等软件&#xff0c;那么我们就避免不了要对内存中的文件进行扫描&#xff0c;音乐播放器我们可以使用android自带的MediaProvider进行处理&#xff0c;而其他的不是媒体文件就要我们自己处理了&#xff0c;接下来我将介绍两…

android 扫描指定文件,Android扫描指定文件和目录

1&#xff0e;启动MediaScanner服务&#xff0c;扫描媒体文件&#xff1a; 程序通过发送下面的Intent启动MediaScanner服务扫描指定的文件或目录&#xff1a; Intent.ACTION_MEDIA_SCANNER_SCAN_FILE&#xff1a;扫描指定文件 public void scanFileAsync(Context ctx, String f…

Python 实现文件关键字扫描

该Python脚本实现了一个简单的扫描器&#xff0c;用于在指定路径下查找指定类型的文件&#xff08;此处以.php文件为例&#xff09;&#xff0c;并对文件内容进行扫描&#xff0c;查找包含特定命令或函数的行。 具体流程如下&#xff1a; spider()函数用于遍历指定路径下的文…