从Leetcode 每日一题练习继续讨论:
3133. 数组最后一个元素的最小值
3133. Minimum Array End
题解
本题仍然是一道位运算相关的题目,要得到题目中的目标结果,必然要以x作为起始数字,因为按位与得到的结果不大于参与运算的数字,则若将x和小于x的数字做按位与,得到的结果必然小于x,不可能满足题目要求。考虑比x大的数字若要与x进行按位与后仍等于x,则该数字必须满足所有x中为1的二进制位也为1。则我们要得到的是从小到大排列的满足该条件的数字中第n大(包含x)的数字。考虑如何构造这样的数字,可以通过固定必须为1的二进制位,再去填充其余二进制位来得到这样的数字,因为我们只要得到第n大的数,不需要产生中间的数字,则直接将n-1(第n大包含x,去掉x还剩n-1个数)的二进制从低到高按位填入x从低到高的0二进制位中即得最终结果。如图
代码
class Solution {
public:
long long minEnd(int n, int x) {
long long int xlong = x;
long long int bitadd = n-1;
long long int copyx = xlong;
int xcurrent = 0;
int bitaddcurrent = 0;
int shift = 0;
while(bitadd > 0){
xcurrent = copyx & 1;
if (xcurrent == 0){
bitaddcurrent = bitadd & 1;
if (bitaddcurrent == 1){
xlong |= ((long long int)1 << shift);
}
bitadd = bitadd >> 1;
}
copyx = copyx >> 1;
shift++;
}
return xlong;
}
};