《leetCode》:Counting Bits
タイトル
Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate 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.
構想一:run time O(n*sizeof(integer))
ヒントに示すように,時間複雑度がO(n*sizeof(integer))であれば,かなり簡単である.すなわち,各数のバイナリ表現のうち1の個数がどれだけであるかを順次判断する.
こんな考えでやれば、ACができないと思っていたのに、意外にもACができた.
考え方2:時間複雑度O(n)
考え方:num<2の場合結果:0 1 num<4の場合結果:0 1 1 2 num<8の場合結果:0 1 1 2,1 2 3
以上の結果から分かるように、2^i~(2^(i+1))-1区間における数が1を含む個数は、対応する0~(2^i)-1の個数に1を足す.すなわち
実装コードは次のとおりです.
Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate 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.
構想一:run time O(n*sizeof(integer))
ヒントに示すように,時間複雑度がO(n*sizeof(integer))であれば,かなり簡単である.すなわち,各数のバイナリ表現のうち1の個数がどれだけであるかを順次判断する.
int countBitOne(int a){
if(a<0){
return 0;
}
int count=0;
while(a){
int temp=a%2;
count+=temp;
a=a>>1;
}
return count;
}
int* countBits(int num, int* returnSize) {
if(num<0){
return NULL;
}
int *res=(int *)malloc((num+1)*sizeof(int));// : num+1
for(int i=0;i<=num;i++){
res[i]=countBitOne(i);
}
*returnSize=num+1;
return res;
}
こんな考えでやれば、ACができないと思っていたのに、意外にもACができた.
考え方2:時間複雑度O(n)
考え方:num<2の場合結果:0 1 num<4の場合結果:0 1 1 2 num<8の場合結果:0 1 1 2,1 2 3
以上の結果から分かるように、2^i~(2^(i+1))-1区間における数が1を含む個数は、対応する0~(2^i)-1の個数に1を足す.すなわち
res[pow(2,i)+j]=res[j]+1;0<=j<pow(2,i) pow(2,i)+j<=num;
実装コードは次のとおりです.
int mypow(int a,int b){
int res=1;
for(int i=0;i<b;i++){
res*=a;
}
return res;
}
int* countBits(int num, int* returnSize) {
if(num<0){
return NULL;
}
int *res=(int *)malloc((num+1)*sizeof(int));// : num+1
if(res==NULL){
printf("malloc failure");
}
res[0]=0;
*returnSize=num+1;
if(num==0){
return res;
}
res[1]=1;
if(num==1){
return res;
}
// num num 2
int n=num;
int count=1;
while(n!=1){
n=n>>1;
count++;
}
for(int i=1;i<count;i++){
int powValue=mypow(2,i);
for(int j=0;powValue+j<=num&&j<powValue;j++){// : powValue+j<=num
res[powValue+j]=res[j]+1;
}
}
return res;
}