LeetCode 338. Counting Bits
2020-05-28 20:12:34
# leetcode
Problem
1. 题目简述
给出一个非负整数num,计算从0到num每个数字二进制表示中1的个数,并以数组形式返回。
Input: 5
Output: [0,1,1,2,1,2]
2. 算法思路
Brute Force
首先最暴力的解法肯定是每次向右移动一位,计算当前数字除以2的余数是多少,然后加和。
暴力解法(进阶版)
比如说对于32,二进制表示为“100000”,需要移动5次,计算6次,这很明显是不合理的嘛,因此就用到了一个十分巧妙的方法去掉末尾的0。
$$n = n & (n - 1)$$
以32举例,31的二进制表示是“11111”,和32做&操作后,n变为0,将从右至左第一个1给消除掉了,减少了很多不必要的运算。
Dynamic Programming
这种方法比较巧妙,我们其实可以找规律。我们假设从1找到8的二进制写法:
0 -> 0
1 -> 1
2 -> 10
3 -> 11
4 -> 100
5 -> 101
6 -> 110
7 -> 111
8 -> 1000
我们找一下规律,从4到7,不外乎就是把0、1、2、3四个数的二进制数前面加个1,多了一个1;我们可以想象,从8到15,也就是比从0到7每个数多了一个1,因此我们用一个lower变量表示比8小的每个数的1的个数,当到达下一个节点时,更新lower为1.
3. 解法
Dynamic Programming
1 |
|
暴力解法进阶版:
1 | class Solution { |