六月集训(第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;
    }
};
posted @ 2022-06-10 09:09  番茄元  阅读(30)  评论(0)    收藏  举报