
2026-07-12:达到目标异或值的最少删除次数。用go语言,给定一个整数数组 nums 和一个整数 target。
你可以从 nums 里删除任意多个元素(也可以一个都不删)。删除之后,剩下的元素组成一个新数组。要求:这个新数组所有元素的“按位异或”结果必须等于 target。
请计算达到上述条件所需的最少删除次数。如果无论怎么删除都无法让剩余元素的按位异或结果等于 target,则返回 -1。
注意:如果你把数组删空,那么空数组的按位异或结果规定为 0。
1 <= nums.length <= 40。
0 <= nums[i] <= 10000。
0 <= target <= 10000。
输入: nums = [1,2,3], target = 2。
输出: 1。
解释:
移除 nums[1] = 2 后剩余 [nums[0], nums[2]] = [1, 3]。
[1, 3] 的异或和为 2,等于 target。
无法在少于 1 次移除的情况下达到异或和 = 2,因此答案为 1。
题目来自力扣3877。
maxVal;bits.Len 获取 maxVal 二进制所占位数 m;1 << m(2的m次方),代表所有可能出现的异或结果;1<<m 都小于 target,直接返回-1(不可能凑出目标值)。f[xorVal] 的含义:能凑出异或值为xorVal的子集,最多包含多少个元素。
1<<m 的数组f;math.MinInt,代表该异或值暂时无法构造;f[0] = 0:空子集异或为0,包含0个元素,是初始合法状态。这是标准01背包型异或动态规划,每个数字只有两种选择:保留 / 删除。 对数组中每一个数字x,执行完整一轮状态更新:
f 得到临时数组 nf,nf 代表「不选当前x」的所有状态(不修改原始f,避免同轮重复选取同一个x);j:f[j] 是极小值,说明该异或值无法构造,直接跳过;j ^ x,新子集元素数量为 f[j] + 1;nf[j^x] 和新数量,取更大值存入 nf[j^x]:保证每个异或值记录最多元素个数;nf 赋值给f,完成当前数字的决策更新。f[target]:该值是凑出异或target的最大元素数量;f[target] < 0:不存在任何子集满足异或等于target,返回-1;len(nums) − 最多保留元素 f[target]。1<<2=4,值域0~3,target=2在范围内;设:
完整流程时间开销:
总时间复杂度:O(n × 2^m) 代入上限:n=40,2^14=16384,总运算量约40 × 16384 = 655360,计算量极小。
总额外空间复杂度:O(2^m) 上限为2^14=16384个int,空间开销极低。
.
package main
import (
"fmt"
"math"
"math/bits"
"slices"
)
func minRemovals(nums []int, target int)int {
m := bits.Len(uint(slices.Max(nums)))
if1<<m <= target {
return-1
}
f := make([]int, 1<<m)
for i := range f {
f[i] = math.MinInt
}
f[0] = 0
for _, x := range nums {
nf := slices.Clone(f)
for j, fj := range f {
nf[j^x] = max(nf[j^x], fj+1) // x 不选 or 选
}
f = nf
}
if f[target] < 0 {
return-1
}
returnlen(nums) - f[target]
}
func main() {
nums := []int{1, 2, 3}
target := 2
result := minRemovals(nums, target)
fmt.Println(result)
}

.
# -*-coding:utf-8-*-
from typing import List
import math
def minRemovals(nums: List[int], target: int) -> int:
# 计算 nums 中最大值需要的二进制位数
max_num = max(nums) if nums else0
m = max_num.bit_length()
# 如果所有可能异或值的范围小于等于 target,则无法达到 target
if (1 << m) <= target:
return-1
# dp数组,f[state] 表示异或结果为 state 时最多能选择的数字个数
# 初始化为极小值
f = [-math.inf] * (1 << m)
f[0] = 0
for x in nums:
# 复制当前dp状态
nf = f.copy()
for j, fj in enumerate(f):
if fj != -math.inf: # 只处理可达状态
new_state = j ^ x
nf[new_state] = max(nf[new_state], fj + 1)
f = nf
# 如果 target 不可达
if f[target] < 0:
return-1
# 最少移除数 = 总长度 - 最多保留数
returnlen(nums) - f[target]
def main():
nums = [1, 2, 3]
target = 2
result = minRemovals(nums, target)
print(result)
if __name__ == "__main__":
main()
.
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
#include <cmath>
using namespace std;
int minRemovals(vector<int>& nums, int target) {
// 计算 nums 中最大值需要的二进制位数
int maxNum = *max_element(nums.begin(), nums.end());
int m = 0;
while ((1 << m) <= maxNum) {
m++;
}
// 如果所有可能异或值的范围小于等于 target,则无法达到 target
if ((1 << m) <= target) {
return-1;
}
// dp数组,f[state] 表示异或结果为 state 时最多能选择的数字个数
// 初始化为极小值
int size = 1 << m;
vector<int> f(size, INT_MIN);
f[0] = 0;
for (int x : nums) {
// 复制当前dp状态
vector<int> nf = f;
for (int j = 0; j < size; j++) {
if (f[j] != INT_MIN) { // 只处理可达状态
int newState = j ^ x;
nf[newState] = max(nf[newState], f[j] + 1);
}
}
f = nf;
}
// 如果 target 不可达
if (f[target] < 0) {
return-1;
}
// 最少移除数 = 总长度 - 最多保留数
return nums.size() - f[target];
}
int main() {
vector<int> nums = {1, 2, 3};
int target = 2;
int result = minRemovals(nums, target);
cout << result << endl;
return0;
}

·
我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。
·