力扣-题号2997
2997. 使数组异或和等于 K 的最少操作次数
题目
给你一个下标从 0 开始的整数数组
nums
和一个正整数k
。你可以对数组执行以下操作 任意次 :
- 选择数组里的 任意 一个元素,并将它的 二进制 表示 翻转 一个数位,翻转数位表示将
0
变成1
或者将1
变成0
。你的目标是让数组里 所有 元素的按位异或和得到
k
,请你返回达成这一目标的 最少 操作次数。注意,你也可以将一个数的前导 0 翻转。比方说,数字
(101)2
翻转第四个数位,得到(1101)2
。
示例一
输入:nums = [2,1,3,4], k = 1
输出:2
解释:我们可以执行以下操作:
- 选择下标为 2 的元素,也就是 3 == (011)2 ,我们翻转第一个数位得到 (010)2 == 2 。数组变为 [2,1,2,4] 。
- 选择下标为 0 的元素,也就是 2 == (010)2 ,我们翻转第三个数位得到 (110)2 == 6 。数组变为 [6,1,2,4] 。
最终数组的所有元素异或和为 (6 XOR 1 XOR 2 XOR 4) == 1 == k 。
无法用少于 2 次操作得到异或和等于 k 。
示例二
输入:nums = [2,0,2,0], k = 0
输出:0
解释:数组所有元素的异或和为 (2 XOR 0 XOR 2 XOR 0) == 0 == k 。所以不需要进行任何操作。
提示
1 <= nums.length <= 105
0 <= nums[i] <= 106
0 <= k <= 106
题解
分析
题目里提到了两个关键词:
- 按位异或
- 二进制
按位异或:同则为0
,异则为1
,任何数和0
异或都等与它本身
例如: 2 XOR 3 = 1
3(十进制) = ...0011(二进制) int 类型前面还有28个0
2(十进制) = ...0010(二进制) int 类型前面还有28个0
1(十进制) = ...0001(二进制) int 类型前面还有28个0
二进制:位运算,左移<<
,右移>>
,不足补零,每移动一位相当于十进制数除以2
题目里要求最终数组里所有数按位异或后的值等于指定值,那么最终数组的所有值再加上指定值一起异或是不是应该等于0
,毕竟相同数异或后等于0
那么问题是不是变成了如何使所有数异或并调整后(翻转)后等于0
,想到这问题就简单了,我们只需把所有数异或后得到的数的二进制形式中的1
全部翻转成0
就行了,那么所需的步骤也就是其中1
的个数
AC代码(C语言)
分析完毕,不多哔哔,上代码
int minOperations(int* nums, int numsSize, int k) {
int count = 0;//统计1的个数
for(int i = 0; i < numsSize; i++) {
k = k ^ nums[i];//将所有值与K异或
}
while(k != 0) {//把异或结果不断右移,统计其中1的个数
if(k & 1) {//&按位与运算,同时为1则结果为1,其他为0,例:010&001=000=0(十进制), 111&001=001=1
count++;
}
k >>= 1;
}
return count;
}
结束语
这题看上去挺唬人的,想通了,其实也没什么,也就那几行代码
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】