leetcode 191. Number of 1 Bits

leetcode 191. Number of 1 Bits

Description

Write a function that takes an unsigned integer and returns the number of ‘1’ bits it has (also known as the Hamming weight).

Note:

Note that in some languages, such as Java, there is no unsigned integer type. In this case, the input will be given as a signed integer type. It should not affect your implementation, as the integer’s internal binary representation is the same, whether it is signed or unsigned.
In Java, the compiler represents the signed integers using 2’s complement notation. Therefore, in Example 3, the input represents the signed integer. -3.

Oral process of solving problems

begin at 00:30
youtube: leetcode 191. Number of 1 Bits
b站 leetcode 191. Number of 1 Bits python
we are told to write a function that takes in an unsigned integer which isn’t really important for this problem. all we want to do is count the number of one bits that it has. the concept is pretty simple. when you take a look at this number, we can see it’s made up of zeros and ones. we just want to count how many ones it has.

Input: n = 00000000000000000000000000001011
Output: 3
Explanation: The input binary string 00000000000000000000000000001011 has a total of three ‘1’ bits.

clearly it has one two three so we can return three. but how can we actually count the bits? obviously we need to do a little bit of bit manipulation.I’m going to be showing you two different solutions. the second one is going to be slightly faster, if you’re interested in
it and it’s pretty difficult to come up with. the first solution is a little bit more straightforward and is more doable.like i said the easiest way is just to count manually bit by bit. then see which one of them is ones. Then increment our total and then return the total. let’s see how we can actually accomplish that.

 1 0 1 1
       ^

we want to look at the first a bit on the right side. how do we know if it’s a one or a zero? there’s actually two different ways.

   1 0 1 1
 & 0 0 0 1

one way is you can and it with the integer one.since the integer one just has a one here and then the rest of them are zeros. when we do a bitwise and operation, bitwise and is basically taking the and of every bit. we know that every bit is gonna be zero when we take the bitwise and. it’s gonna be zero for every bit except for this one which can either be zero or one. it’ll be one if the bit in the input integer is one then we’ll get a one in the output. if it’s a zero over here then we’ll get a zero in the output. so that can tell us if there’s a 1 here or a 0 here.

another way to do it is just to mod this by 2. modding is basically taking this dividing it by 2 and getting the remainder. since this is the ones place, if we mod it by two, and there is a one here, we’ll get a one in the output. if there’s a zero here, we’ll get a zero in the output. so we have two different ways to do it. I think i’m gonna stick with modding, but you can do it either way.

we have a way to detect if the first bit is a one or a zero. but what if we want to look at the next bit how do we do that? the easiest way would just be to take all the rest of the bits and then shift them to the right by one. luckily most languages can natively support this and it’s a very efficient cpu operation. this is kind of the preferred way to usually do it in bit manipulation just shift every bit to the right by one. we can achieve basically the exact same thing by taking this and then integer division by two. dividing it by two will basically shift all the bits to the right by one as well. usually the bit shift operation is a little bit more efficient on your cpu so that’s what i’m going to prefer.

   1 0 1 1 >> 1 = 1 0 1

so basically we’re going to take these shift them to the right. now we’re going to have a new integer 101. again we want to know if this bit is 1 or 0. we’re going to mod it by 2. we’re going to get another one. So far we have counted two : two ones. again we would want to take these shift them to the right. this time we get a 10. we mod this by two. we get a zero in the output that means there’s a zero here. so we don’t add to our total this time. lastly we take this shift it by one we get another. we basically get the integer one. we mod it by two. one divided by two the. remainder after that is just one. so we got our third one. our total so far is three ones that we counted.

lastly we’re going to take this and then shift it to the right. what exactly is going to be remaining after we do that well basically zero. once we have a zero it basically means we have all zeros. 32 bit integer we’ll have 32 zeros. that basically means that we can stop our algorithm now. we’re done. we counted in total three ones and that’s what we can return.

once you’re familiar with these bit operations, it’s a pretty straightforward problem. let’s code up the first solution okay. let’s code it up. I’m going to declare one variable for the result which is basically the total account. the total number of ones that we’re going to have and i’m going to continue counting the ones. while n is greater than zero or, in other words while it’s not equal to zero. we want to know if the ones place is a one or a zero, so we can take n and mod it by two.

res += n%2

this will either be a one or this will be a zero. if it’s a one, we increment result. if it’s a zero, we don’t increment result. in other words we can just basically add this to our result itself. we don’t want to forget to shift everything to the right by one. what we can do is set n equal to itself bit shifted to the right by one. after that last thing we have to do is just return the result. let’s run it to make sure that it works. as you can see it does work and it is pretty efficient.
在这里插入图片描述
what exactly is the time complexity of the solution well. the good thing is that we’re guaranteed that every input is going to be a 32-bit integer. so we know that that while loop we had is going to run 32 times. the time complexity is O(32) (big o of 32) which is constant time. no matter what the input is, the time complexity is not going to scale up. basically the time complexity is constant. we can say it’s big o of one. there’s no real extra memory complexity needed as well, so that’s also big o of one. but a small downside of our solution is, it has to look at every bit even the ones that aren’t ones.

for example what if we had a number like this 100001.in this case we’re gonna look at this bit first. okay it’s a one. we’re done with that then we’re going to look at every bit here even though they’re zeros. that kind of wastes time. wouldn’t it be convenient if we only had to look at the bits that were one. that meaning our algorithm only has to run as many times as how many ones are actually in the input. there actually is a way we can do this but it’s not very easy to come up with. it’s probably not even worth coming up with because the time complexity will be the same. it’ll still be constant time and constant space. it might be good to get really good at your bit manipulation tricks and stuff and maybe you’ll see this in an interview.

n = n & (n - 1)

the main operation we’re going to be doing in our while loop with this trick is basically taking n and setting it equal to n bitwise and with n minus one. this is what we’re going to do in every iteration of the loop. each time we do that we’re going to increment our result by one. but the question is why does this work. first let’s see what will happen. let’s take this integer (1000001) and subtract one from it. that’s what we’re do over here, so n minus 1 which is going to be this(1000000). we’re going to bitwise and them together. what are we going to get when we do that we’re basically going to be removing this right (1000001 & 1000000 =1000000). this we’re going to get n minus 1 itself. we’re also going to increment our result by 1, regardless of what the output happens to be.

   1000000
 & 0111111

our n value is going to be set to this(1000000). now our new value is going to be one and all zeros (1000000). we’re going to take this number and subtract one from it. what is that going to look like in binary. it’s going to be 0111111. we are gonna bitwise and these two together. what’s that gonna look like. we’re bitwise and every bit. this one is gonna turn into zero. the rest of these are also be zero even though we have ones in the bottom number we have all zeros in the number above. we’re actually done with our entire loop now. we incremented our result by two. so our result is two. and then we return right which makes sense because when you look at the original number we started with it. it did have two ones in it.

how did this algorithm work well? it’s actually really simple but it’s definitely not easy to come up with. what we’re doing when we’re subtracting one from itself is we’re basically getting rid of a bit. when we took this number and subtracted one from it. we got rid of this one bit. remember we’re counting one bits so when we did that we increment our result by one. why did we bitwise and it together with itself? well basically since the rest of the numbers stayed the same. we took this one away here and then we bitwise and them together. we’re basically removing that one bit. when we bitwise and these two together, you can see that the one bit was removed but the rest of the number stayed the exact same on the left.

what about this number? (100000) we were left with this and then we subtracted one from it. we do well again when we subtracted one from it we basically got rid of the next one bit. you can see that when we subtracted one from it this is what the number looked like we got rid of this one bit. we introduced a bunch of other one bits but these are all okay. because we know they’re gonna be and any one bits that we introduce are going to be on the right side. we know that if we just deleted this one it was the it was the right most one bit that we had. so any ones that are introduced to the right side won’t matter in this number.this is n minus 1 by the way any ones here won’t matter.

class Solution(object):
    def hammingWeight(self, n):
        """
        :type n: int
        :rtype: int
        """
        res = 0

        while n!=0:
            res += 1
            n = n & (n-1)

        return res

youtube: EPI 4.1 Computing The Parity Of A Word In Python.

Computing The Parity Of A Word

Description

the parity of a binary word is 1 if the number of 1s in the word is odd; otherwise, it is 0; Parity checks are used to detect single bit errors in data storage and communication. It is fairly straightforward to write code that computes the parity of a single 64-bit word. How would you compute the parity of a very large number of 64-bit words?

Example

the parity of 1011 is 1
the parity of 10001000 is 0

code

short Parity(unsigned long x)
{
	short result =0;
	while(x)
	{
		result  ^= (x&1);
		x>>=1;
	}
	return result;
}

the time complexity is O(n), where n is the word size.

short Parity(unsigned long x)
{
	short result = 0;
	while(x)
	{
		result ^= 1;
		x &= (x-1);
	}
	return result;
}

the time complexity is O(k), where k is the number of bits set to 1 in a particular. it improve performance in the best- and average-case.

Oral process of solving problems

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值