2859. 计算 K 置位下标对应元素的和

1.题目介绍

2.题解

2.1 枚举

思路

这里你只要知道 num % 2 相当于是取到二进制最后一位, num / 2 是将二进制整体向右推移一位即可

代码

class Solution {
public:
    int sumIndicesWithKSetBits(vector<int>& nums, int k) {
        int ans = 0;
        for(int i = 0; i < nums.size(); i++){
            int count = 0 , temp = i;
            while(temp != 0){
                if(temp % 2 != 0) count++;
                temp /= 2;
            }
            if(count == k) ans += nums[i];
        }
        return ans;
    }
};

复杂度分析

时间复杂度:O(nlog⁡n),其中 n 是数组 nums 的长度。对于每个下标,我们需要 O(log⁡n)的时间计算它的置位个数(类似二分法的时间复杂度,不断除2?)。
空间复杂度:O(1)。

2.2 对计算置位个数进行优化

思路



总体思路就是分治思想,将数的二进制拆为两部分,然后再通过移位(将第二组从高位移到相对低位)将其置于同一水平线(这里理解为低位)上,直接相加
第一步:比如像这里第一次就能获得 a+b, c+d, e+f, g+h, i+j的值并且分别存储在新的x(相对低位中)中{类似 (a+b) (c+d) (e+f)...的感觉,由于原本高位的0不占实际值,这里的a+b, c+d, e+f因为有可能进位,都是占据两位的!!!后面可以将ab,cd,ef...看做一个整体进行运算}
总而言之,这里虽然结果还写作(abcdefghij),但表示的意义不同, 就拿ab来说,假设 a = 1, b= 1 之前ab就是 11, 现在ab 是01+01=10!!!
其实就是拿二进制的两位存储二者相加的结果,作为一个中间存储地。

第二次通过新的x又能获得 a+b, c+d+e+f, g+h+i+j的值,这里就是拿二进制的四位来存储后两者的和了

第三次,这时高两位是a+b的结果,中间四位是c+d+e+f的结果,最后四位是g+h+i+j的结果,通过移位将这三者相加就得到了a+b+c+d+e+f+g+h+i+j的值,也就是我们需要的置位数。

代码

auto bitCount = [](int x) 不是一个数据结构,而是一个 lambda 表达式

  • [capture]:这是一个捕获列表,用于指定 lambda 表达式访问的外部变量。
  • (int x):这是参数列表,指定 lambda 表达式接受一个整数参数 x。
  • -> return_type:这是返回类型,指定 lambda 表达式返回一个特定的类型。
  • { /* function body */ }:这是 lambda 表达式的主体,包含实际的计算逻辑。
    总而言之就是定义了一个可以计算整数二进制表示中包含的 1 的个数的 lambda 表达式,并将其赋值给 bitCount
class Solution {
public:
    int sumIndicesWithKSetBits(vector<int>& nums, int k) {
        auto bitCount = [](int x) {
            x = (x & 0b0101010101) + ((x & 0b1010101010) >> 1);
            x = ((x & 0b0011001100) >> 2) + (x & 0b1100110011);
            x = (x >> 8) + ((x >> 4) & 0b1111) + (x & 0b1111);
            return x;
        };

        int ans = 0;
        for (int i = 0; i < nums.size(); ++i) {
            if (bitCount(i) == k) {
                ans += nums[i];
            }
        }
        return ans;
    }
};

复杂度分析

时间复杂度:O(nlog⁡log⁡C),其中 nnn 是数组 nums的长度,CCC 是数组 nums 的最大长度。
上述的分治算法在第 p (p≥0) 步时,会将每连续 2^p的二进制位看成一个整体进行相加。
C 有 O(log⁡C)个二进制位,因此分治需要 O(log⁡log⁡C) 次。
空间复杂度:O(1)。

posted @   DawnTraveler  阅读(30)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 我与微信审核的“相爱相杀”看个人小程序副业
· DeepSeek “源神”启动!「GitHub 热点速览」
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示