338.Counting Bits
Tags: [bit_manipulation], [math], [dp]
Link: https://leetcode.com/problems/counting-bits/\#/description
Given a non negative integer numbernum. For every numbersiin the range0 ≤ i ≤ numcalculate the number of 1's in their binary representation and return them as an array.
Example:
For num = 5
you should return[0,1,1,2,1,2]
.
Follow up:
- It is very easy to come up with a solution with run time O(n*sizeof(integer)). But can you do it in linear time O(n)/possibly in a single pass?
- Space complexity should be O(n).
- Can you do it like a boss? Do it without using any builtin function like __builtin_popcount in c++ or in any other language.
Solution: DP
class Solution(object):
def countBits(self, num):
"""
:type num: int
:rtype: List[int]
"""
if num < 0:
raise ValueError('The input is invalid')
if num == 0:
return [0]
if num == 1:
return [0, 1]
if num == 2:
return [0, 1, 1]
counters = [0 for _ in xrange(num + 1)]
counters[0] = 0
counters[1] = 1
counters[2] = 1
for n in xrange(3, num + 1):
if n % 2 != 0:
counters[n] = counters[n - 1] + 1
else:
counters[n] = counters[n / 2]
return counters
Revelation:
- We can first use straight forward method to solve this problem, (the straight forward solution list below).
For this kind of question, if we think there exists some tricks, we can list some small number example:
num = 0, result = [0], n = 0, num of '1's bits = 0
- num = 1, result = [0, 1], n = 1, num of '1's bits = 1
- num = 2, result = [0, 1, 1], n = 2, num of '1's bits = 1
- num = 3, result = [0, 1, 1, 2], n = 3, num of '1's bits = 2
- num = 4, result = [0, 1, 1, 2, 1], n = 4, num of '1's bits = 1
- num = 5, result = [0, 1, 1, 2, 1, 2], n = 5, num of '1's bits = 2
- num = 6, result = [0, 1, 1, 2, 1, 2, 2], n = 6, num of '1's bits = 2
- num = 7, result = [0, 1, 1, 2, 1, 2, 2, 3], n = 7, num of '1's bits = 3
- num = 8, result = [0, 1, 1, 2, 1, 2, 2, 3, 1], n = 8, num of '1's bits = 1
- num = 9, result = [0, 1, 1, 2, 1, 2, 2, 3, 1, 2], n = 9, num of '1's bits = 2
- num = 10, result = [0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2], n = 10, num of '1's bits = 2
- num = 11, result = [0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3], n = 11, num of '1's bits = 3
- num = 12, result = [0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2], n = 12, num of '1's bits = 2
- num = 13, result = [0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3], n = 13, num of '1's bits = 3
num = 14, result = [0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3], n = 14, num of '1's bits = 3
From the above example, when num >= 3, there exists the regulation, which is that: if current n is odd number, the number of '1's bits = the number of '1's bits of (n - 1). If the current n is even number, the number of '1's bits = the number of '1's bits of (n/2).
Note:
- Time complexity = O(num).
Straight forward solution:
class Solution(object):
def countBits(self, num):
"""
:type num: int
:rtype: List[int]
"""
if num < 0:
raise ValueError('the input should be less than 0')
counters = [0 for _ in xrange(num + 1)]
for i in xrange(32):
for n in xrange(num + 1):
if (n >> i) & 1 == 1:
counters[n] += 1
return counters
Note:
- Time complexity = O(num).