力扣—第338题—比特位计数,官方解法二(c++)分析

本文详细分析了LeetCode第338题的C++官方解法二,重点讲解了位与运算在解决此问题中的关键作用。通过例子解释了如何找到最高有效位,并展示了如何利用位运算求解位计数问题。此外,还探讨了代码中初始化vector的细节和数组更新的逻辑。

一、原题原解法

在这里插入图片描述官方给的解法二:
在这里插入图片描述解法代码:

class Solution {
public:
   vector<int> countBits(int num) {
       vector<int> bits(num + 1);
       int highBit = 0;
       for (int i = 1; i <= num; i++) {
           if ((i & (i - 1)) == 0) {
               highBit = i;
           }
           bits[i] = bits[i - highBit] + 1;
       }
       return bits;
   }
};

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/counting-bits/solution/bi-te-wei-ji-shu-by-leetcode-solution-0t1i/
来源:力扣(LeetCode)

运行情况:在这里插入图片描述

二、个人补充分析

首先我们要明白其中的几个关键的原理:
第一:位与运算:&
寻找最高有效位的时候用的代码是:i & (i - 1)==0
根据题目的意思最高有效位是:20,21,22,23
相应的二进制码是:0,10,100,1000
只有最高有效位与比起少1的数字,位与计算才是0,比如 4&3=100&011=0


解释:位与计算‘&’:是指参加运算的两个数,按二进制位进行“与”运算。
运算规则:只有两个数的二进制同时为1,结果才为1,否则为0。(负数按补码形式参加按位与运算。即 0 & 0= 0 ,0 & 1= 0,1 & 0= 0, 1 & 1= 1。
比如:5&6=101&110=100=4

第二: y为 x 的「最高有效位」。令 z=x−y,显然 0≤z<x 则 bits[x]=bits[z]+1(也就是 bits[x]=bits[z]+bits[y])
代码: bits[i] = bits[i - highBit] + 1;
分析:
输入:    0, 1,  2 ,   3,   4,     5,   6,    7
二进制:0,1,10,11,100,1001,1010,1011
1的个数: 0,1, 1, 2,   1,    2,   2,    3
规律:bit[任一比最高效位数字大的数] 减去 bit[ 最高效位数]=bit[两者之差]
即:bit[4]+bit[3]=bit[7];

这就是这种方法所需要的最主要的原理了

总结:
原理一:知道最高效位的概念
原理二: 最高效位的运算


接下来补充一点其余有些难懂的地方:
比如
第一:
vector bits(num + 1);
  查阅资料发现,这个创建对象名还调用了指定的构造函数。因为这个构造函数在LeeCode的类Solution内部,我们看不到。
  不过可以猜想,这里面含有像new这样开辟空间的函数,所以需要加上(num+1)的参数,而且num+1正好是0到num需要的空间大小。有意思的是,这个开辟空间之后为自动初始化为0;
第二:
  bit[]数组为什么没有赋值,因为i是从1开始递推的。所以后面的数组bit[i]都在前面找得到,bit[1]是从bit[0]推过来的,bit[0]在之前调用 vector bits(num + 1);就会被初始化为0,

下面是我在官方的代码上加了点自己的注释(VS2019):

#include<iostream>
#include<vector>
using namespace std;
void disaplay(vector<int> &temp)
{
 typename vector<int>::iterator it;
 for (it = temp.begin(); it < temp.end(); it++)
 {
     cout << *it;
 }
 cout << endl;

}

class Solution {
public:
 vector<int> countBits(int num) {
     vector<int> bit(num+1);//调用特殊的构造函数,并且默认值都是0,所以没必要给bit[0]=0;
     int highbit = 0;

     for (int i=1;i<=num;i++)
     {
         if ((i & (i - 1)) == 0)//判断是否是最高有效位,i会大于highbit
             highbit = i;
         bit[i] = bit[i - highbit] + 1;//bit[highbit]+bit[i]=bit[highbit+i],i是递进的,i以前的bit都已经存入了
     }

     return bit;


 }
};

int main()
{
 Solution solu;
 vector<int> temp;
 temp = solu.countBits(2);
 disaplay(temp);

 return 0;
}

如果觉得对你有帮助,那就赞一下吧!
如果你觉得有不足之处或者意见,可以评论指出交流!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值