leetcode 338 Counting Bits 详细解答
以例子说明:
Index : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
bin nums : 0 1 1 2 1 2 2 3 1 2 2 3 2 3 3 4 1 2
解法1
这里极其容易通过观察得出:
f ( i ) = { f ( i − 2 ) + 1 2 < = i < = 3 f ( i − 4 ) + 1 4 < = i < = 7 f ( i − 8 ) + 1 8 < = i < = 15 f(i)=\begin{cases} f(i-2)+1 & 2<=i<=3 \\ f(i-4) + 1 & 4<=i<=7 \\ f(i-8)+1 & 8<=i<=15 \end{cases} f(i)=⎩⎪⎨⎪⎧f(i−2)+1f(i−4)+1f(i−8)+12<=i<=34<=i<=78<=i<=15
上述问题相当于是个动态规划问题,如果表示成一个通项,即是:
f ( i ) = f ( i − 2 i n t ( l o g 2 i ) ) + 1 f(i)= f(i - 2^{int(log_2{i})}) + 1 f(i)=f(i−2int(log2i))+1
代码如下:
解法2
在解法1中,时间复杂度是O(N),但因为到要做指数运算和对数运算,所以执行的速度会慢很多。
改进
这里通过设置一个offset来进行改进。通过观察:
f ( 2 , . . . , 3 ) = f ( 0 , . . . , 1 ) + 1 f(2,...,3) = f(0,...,1) + 1 f(2,...,3)=f(0,...,1)+1
f ( 4 , . . . , 7 ) = f ( 0 , . . . , 3 ) + 1 f(4,...,7) = f(0,...,3)+ 1 f(4,...,7)=f(0,...,3)+1
f ( 8 , . . . 15 ) = f ( 0 , . . . , 7 ) + 1 f(8,...15) = f(0,...,7) + 1 f(8,...15)=f(0,...,7)+1
. . .
. . .
代码如下:
解法3
从二进制的角度来看:
如果 i 是偶数,向右移1位,那么二进制中1的个数还是不变
如果 i 是奇数,向右移1位,那么二进制中1的个数减少了以为
所以状态转移方程:
f ( i ) = f ( i > > 1 ) + ( i & 1 ) f(i) = f(i>>1) + (i {\&} 1) f(i)=f(i>>1)+(i&1)解释:后面的括号必须要加,因为加法的优先级(+)比与(&)要高
最后代码如下: