六月集训(第10天)—位运算
位运算
1. 868. 二进制间距
思路:
记录相邻两个1的位置,作差取最大值即可。
class Solution {
public:
int binaryGap(int n) {
int ans = 0;
int i = 1, j = 0;
while (n) {
if ((n & 1) && !j) {
j = i;
} else if ((n & 1) && j) {
ans = max(ans, i - j);
j = i;
}
i++;
n >>= 1;
}
return ans;
}
};
2. 1734. 解码异或后的排列
思路:
假设perm[] = {A, B, C, D, E};, 则encoded[] = {AB, BC, CD, DE};,于是从perm可得$A xor B xor C xor D xor E$,简记为$ABCDE$,由encoded得奇数项可得$BCDE$,于是就得到了$A = ABCDE xor BCDE$,之后得所有元素就很容易得到了。
class Solution {
public:
vector<int> decode(vector<int>& encoded) {
int encoded_size = encoded.size(), i;
vector<int> ans(encoded_size + 1);
int ABCDE = 0, BCDE = 0;
for (i = 1; i <= encoded_size + 1; ++i) ABCDE ^= i;
for (i = 1; i < encoded_size; i += 2) BCDE ^= encoded[i];
ans[0] = ABCDE ^ BCDE;
for (i = 1; i < encoded_size + 1; ++i) ans[i] = ans[i - 1] ^ encoded[i - 1];
return ans;
}
};
3. 89. 格雷编码
思路:
递归构造格雷码,利用格雷码得性质,n位的格雷码可由n-1位的格雷码与其逆序(并且最高位置为1)组成。
class Solution {
public:
vector<int> grayCode(int n) {
if (n == 1) return {0, 1};
vector<int> ans = grayCode(n - 1);
int ans_size = ans.size(), i;
for (i = 0; i < ans_size; ++i) { /* 将n-1得格雷码从后往前取出,最高位添加1,得到n位格雷码 */
int temp = ans[ans_size - i - 1] | (1 << (n - 1));
ans.push_back(temp);
}
return ans;
}
};
4. 1238. 循环码排列
思路:
同第三问,直接获取一种可行的格雷码,按照start在第一位,其余顺序不变依次填入即可。
class Solution {
vector<int> grey_code(int n) {
if (n == 1) return {0, 1};
vector<int> ans = grey_code(n - 1);
int ans_size = ans.size(), i;
for (i = 0; i < ans_size; ++i) {
int temp = ans[ans_size - i - 1] | (1 << (n - 1));
ans.push_back(temp);
}
return ans;
}
public:
vector<int> circularPermutation(int n, int start) {
vector<int> ans = grey_code(n); /* 首先获取n位格雷码 */
int ans_size = ans.size(), i = 0;
vector<int> new_ans(ans_size);
int cnt = 0;
while (cnt < ans_size) {
if (cnt == 0 && ans[i] == start) { /* 找到起始位置 */
new_ans[cnt++] = ans[i];
} else if (cnt) { /* 将start作为new_ans[0],剩余数值依次填入,到达结尾时返回ans[0]继续填入 */
new_ans[cnt++] = ans[i % ans_size];
}
++i;
}
return new_ans;
}
};
东方欲晓,莫道君行早。

浙公网安备 33010602011771号