分享丨【题单】位运算(基础/性质/拆位/试填/恒等式/思维) - 力扣(LeetCode)
Leetcode 3133. 数组最后一个元素的最小值
我的答案与思路:
class Solution {
public:
// 4 --> (100)2 7 --> (0111)2
// 5 --> (101)2 15--> (1111)2
// 6 --> (110)2
// 插入的时候①1 = (1)10 ②10 = (2)10 ③11 = (3)10 ④100 = (4)10 ⑤101 ⑥110 ⑦111
string getBin(int x){
string ans = "";
while (x){
if(x & 1) ans += "1";
else ans += "0";
x >>= 1;
}
reverse(ans.begin(), ans.end());
return ans;
}
string getInsert(int n){
int sit = n - 1;
return getBin(sit);
}
long long minEnd(int n, int x) {
// x 一定是整个数组中最小的
string xbin = getBin(x);
string inbin = getInsert(n);
int idx = xbin.length() - 1;
for(int i = inbin.length() - 1; i >= 0; i --){
if(idx >= 0){
while(idx >= 0 && xbin[idx] != '0'){
idx --;
} // 找到第一个为"0"的地方
if(idx < 0) xbin = inbin[i] + xbin;
else xbin[idx] = inbin[i];
idx --;
}else
xbin = inbin[i] + xbin;
}
// 将2进制string转换为十进制整数
long long res = 0;
for(auto& v: xbin){
res <<= 1;
res += (v - '0');
}
return res;
}
};
更加优雅的实现方式:从集合论的角度进行实现
class Solution {
public:
long long minEnd(int n, int x) {
n --; // 插入数位就是n - 1
long long res = x;
int i = 0, j = 0;
while (n >> j){
if((res >> i & 1) == 0){ // 当x的第i个bit是0(需要填入数)
// 空位填入n的第j个bit
res |= (long long) (n >> j & 1) << i;
j ++;
}
i ++;
}
return res;
}
};
优化方法:lowbit
把 x 取反,用 lowbit 枚举其中的 1,就是要填的空位。
class Solution {
public:
long long minEnd(int n, int x) {
n --; // 插入数位就是n - 1
long long res = x;
int j = 0;
for (long long t = ~x, lb; n >> j; t ^= lb){
lb = t & -t;
res |= (long long)(n >> j ++ & 1) * lb;
}
return res;
}
};