1863. Sum of All Subset XOR Totals(C语言)回溯法解决子集问题

1863. Sum of All Subset XOR Totals(C语言)

回溯法解决子集问题

题目

The XOR total of an array is defined as the bitwise XOR of all its elements, or 0 if the array is empty.

For example, the XOR total of the array [2,5,6] is 2 XOR 5 XOR 6 = 1.
Given an array nums, return the sum of all XOR totals for every subset of nums.

Note: Subsets with the same elements should be counted multiple times.

An array a is a subset of an array b if a can be obtained from b by deleting some (possibly zero) elements of b.

Example 1:
Input: nums = [1,3]
Output: 6
Explanation: The 4 subsets of [1,3] are:

  • The empty subset has an XOR total of 0.
  • [1] has an XOR total of 1.
  • [3] has an XOR total of 3.
  • [1,3] has an XOR total of 1 XOR 3 = 2.
    0 + 1 + 3 + 2 = 6

Example 2:
Input: nums = [5,1,6]
Output: 28
Explanation: The 8 subsets of [5,1,6] are:

  • The empty subset has an XOR total of 0.
  • [5] has an XOR total of 5.
  • [1] has an XOR total of 1.
  • [6] has an XOR total of 6.
  • [5,1] has an XOR total of 5 XOR 1 = 4.
  • [5,6] has an XOR total of 5 XOR 6 = 3.
  • [1,6] has an XOR total of 1 XOR 6 = 7.
  • [5,1,6] has an XOR total of 5 XOR 1 XOR 6 = 2.
    0 + 5 + 1 + 6 + 4 + 3 + 7 + 2 = 28

Example 3:
Input: nums = [3,4,5,6,7,8]
Output: 480
Explanation: The sum of all XOR totals for every subset is 480.

Constraints:
1 <= nums.length <= 12
1 <= nums[i] <= 20

解答

long long int sum;
void Backtrack(int * nums, int numsSize, int pre_re)//nums是选择列表
{
    int i;
    for(i = 0; i < numsSize; i++)
    {
        int re = pre_re^nums[i];
        sum += re;

        if(i == numsSize-1)//结束条件
            return;

        int *temp = (int *)malloc(sizeof(int)*(numsSize-i-1));
        int j;
        for(j = 0; j < numsSize - i -1; j++)
        {
            temp[j] = nums[j+i+1];
        }

        Backtrack(temp, numsSize-i-1, re);
    }
}
int subsetXORSum(int* nums, int numsSize){
    sum = 0;
    Backtrack(nums, numsSize, 0);
    return sum;
}

总结

思路:利用回溯法解决子集问题
以例2为例:
在这里插入图片描述
回溯法的结构:

int backtrack(路径, 选择列表)
{
	if(满足结束条件)
	{
		...
		return ;
	}
	for 选择 in 选择列表:
	{
		选择(更新路径和选择列表)
		backtrack(路径,选择列表);
		撤销选择(还原路径和选择列表)
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
子集问题是一个经典的组合优化问题,可以使用回溯法(backtracking)进行求解。具体的思路是: 1. 定义一个数组或者集合,存储所有可选的数值。 2. 定义一个数组或者集合,存储当前已选的数值。 3. 定义一个变量,记录当前已选数值的和。 4. 从第一个数开始,遍历可选数值,对于每个可选数值,判断是否可以加入已选数值中。如果可以,则加入已选数值中,更新当前和,并且递归调用解决剩余问题;如果不可以,则不加入已选数值中,继续遍历下一个可选数值。 5. 当已选数值的和等于目标值时,输出当前已选数值,结束递归。 6. 当所有可选数值都遍历完毕,仍未找到解,则回溯到上一个节点,继续遍历下一个可选数值。 下面是 C 语言实现的示例代码: ```c #include <stdio.h> #define MAX_NUM 100 int nums[MAX_NUM]; int selected[MAX_NUM]; int sum, target; int n; void subset_sum(int k) { if (sum == target) { printf("Subset found: "); for (int i = 0; i < n; i++) { if (selected[i]) { printf("%d ", nums[i]); } } printf("\n"); return; } if (k == n || sum > target) { return; } selected[k] = 1; sum += nums[k]; subset_sum(k + 1); sum -= nums[k]; selected[k] = 0; subset_sum(k + 1); } int main() { printf("Enter the number of elements: "); scanf("%d", &n); printf("Enter the elements: "); for (int i = 0; i < n; i++) { scanf("%d", &nums[i]); } printf("Enter the target sum: "); scanf("%d", &target); subset_sum(0); return 0; } ``` 在实际应用中,为了避免重复计算,可以使用记忆化搜索或者动态规划进行优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值