位运算:其他

2021-05-15 每日一题 LeetCode

# 0078. 子集 (opens new window)

题目

给你一个整数数组 nums,数组中的元素互不相同,返回该数组所有可能的子集(幂集)。

解集不能包含重复的子集,你可以按任意顺序返回解集。

解析

由于一个长度为 n 的 nums 数组,其子集个数为 2n2^n,可以用一个二进制串表示每个元素是否出现,依此构建子集。

代码

    # 0137. 只出现一次的数字 II (opens new window)

    题目

    给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。

    解析

    统计所有数字每一位中 1 的数量,如果可以整除 3,说明结果这一位为 0,否则为 1。

    代码

    class Solution {
    public:
        int singleNumber(vector<int>& nums) {
            int ans = 0;
            for (int i = 0; i < 32; i++) {
                int cnt = 0;
                for (auto &num: nums) {
                    cnt += (num >> i) & 1;
                }
                if (cnt % 3) ans |= (1 << i);
            }
            return ans;
        }
    };
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    # 0397. 整数替换 (opens new window)

    题目

    给定一个正整数 n ,你可以做如下操作:

    如果 n 是偶数,则用 n / 2替换 n 。 如果 n 是奇数,则可以用 n + 1 或 n - 1 替换 n 。 n 变为 1 所需的最小替换次数是多少?

    解析

    当 n 为奇数时:

    • 如果倒数第二位是 0,那么 n - 1 操作能消掉更多的 1;
      • 1001 + 1 = 1010
      • 1001 - 1 = 1000
    • 如果倒数第二位是 1,那么 n + 1 操作能消掉更多的 1;
      • 1011 + 1 = 1100
      • 1111 + 1 = 10000

    注意

    • 为了防止越界,需要将 n 转化为长整型计算;
    • 当 n 为 3 时需要进行 n - 1 操作,不满足上面规律,需要特殊讨论。

    代码

      Last Updated: 2023-01-28 4:31:25