持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情
🎈算法并不一定都是很难的题目,也有很多只是一些代码技巧,多进行一些算法题目的练习,可以帮助我们开阔解题思路,提升我们的逻辑思维能力,也可以将一些算法思维结合到业务代码的编写思考中。简而言之,平时进行的算法习题练习带给我们的好处一定是不少的,所以让我们一起来养成算法练习的习惯。今天练习的题目是一道中等难度的题目 -> 最小 XOR
题目描述
给你两个正整数 num1 和 num2 ,找出满足下述条件的整数 x :
x 的置位数和 num2 相同,且 x XOR num1 的值 最小 注意 XOR 是按位异或运算。
返回整数 x 。题目保证,对于生成的测试用例, x 是 唯一确定 的。
整数的 置位数 是其二进制表示中 1 的数目。
示例 1:
输入:num1 = 3, num2 = 5
输出:3
解释:
num1 和 num2 的二进制表示分别是 0011 和 0101 。
整数 3 的置位数与 num2 相同,且 3 XOR 3 = 0 是最小的。
示例 2:
输入:num1 = 1, num2 = 12
输出:3
解释:
num1 和 num2 的二进制表示分别是 0001 和 1100 。
整数 3 的置位数与 num2 相同,且 3 XOR 1 = 2 是最小的。
提示:
- 1 <= num1, num2 <= 10^9
思路分析
首先我们要先理解一下题目的意思,题目会给我们两个正整数num1和num2,要求我们通过这两个正整数求得一个整数x,整数x应该满足以下两个条件:
x的置位数和num2相同,整数的 置位数 是其二进制表示中1的数目x XOR num1的值 最小,XOR是按位异或运算
异或运算
首先我们应该先了解一下什么是异或运算及异或运算规则
异或是一个数学运算符。它应用于逻辑运算。异或的数学符号为“⊕”,计算机符号为“xor”。
其中:真⊕假=真,假⊕真=真,假⊕假=假,真⊕真=假(二进制下用1表示真,0表示假)
解题步骤
- 1、计算
num2的置位数n
let n = 0;
for(let i = 0; i < num2.length; i++){
n += parseInt(num2[i]);
}
- 2、找出置位数为
n,且与num1异或值最小的x (1)初始化x,x的位数应该为num1的位数和置位数n之间的最大值
let x = new Array(Math.max(num1.length,n)).fill(0);
(2)因为异或运算中1 XOR 1 = 0,所以我们只需要从高位向低位遍历,遇到num1中二进制位为1时,x在该位数也补1,并且消耗一个置位数
for(let i = 0;i < num1.length && n > 0; i++){
//x在该位数也补`1`
x[i] = num1[i];
//消耗一个置位数
n -= parseInt(num1[i]);
}
(3)如果置位数未消耗完,我们需要继续在x中补1,这时要使x XOR num1 的值 最小,我们应该优先在低位补1
let len = x.length - 1;
while(n){
while(x[len] == '1' || num1[len] == '1') len--;
if(len < 0) break;
x[len] = '1';
n--
}
(4)二进制转换为10进制
return parseInt(x.join(''),2);
AC代码
/**
* @param {number} num1
* @param {number} num2
* @return {number}
*/
var minimizeXor = function(num1, num2) {
num2 = num2.toString(2);
num1 = num1.toString(2);
let n = 0;
for(let i = 0; i < num2.length; i++){
n += parseInt(num2[i]);
}
let x = new Array(Math.max(num1.length,n)).fill(0);
for(let i = 0;i < num1.length && n > 0; i++){
x[i] = num1[i];
n -= parseInt(num1[i]);
}
let len = x.length - 1;
while(n){
while(x[len] == '1' || num1[len] == '1') len--;
if(len < 0) break;
x[len] = '1';
n--
}
return parseInt(x.join(''),2);
};
说在后面
🎉这里是JYeontu,喜欢算法,GDCPC打过卡;热爱羽毛球,大运会打过酱油。毕业一年,两年前端开发经验,目前担任H5前端开发,算法业余爱好者,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。